auto commit
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 代码编辑:guoyahao
|
||||
* 代码修订:yitter
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package gen
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"yitidgen/contract"
|
||||
)
|
||||
|
||||
var ins *YitIdHelper
|
||||
var once sync.Once
|
||||
|
||||
type YitIdHelper struct {
|
||||
idGenInstance interface {
|
||||
NewLong() uint64
|
||||
}
|
||||
}
|
||||
|
||||
func GetIns() *YitIdHelper {
|
||||
once.Do(func() {
|
||||
ins = &YitIdHelper{}
|
||||
})
|
||||
return ins
|
||||
}
|
||||
|
||||
func (yih *YitIdHelper) GetIdGenInstance() interface{} {
|
||||
return yih.idGenInstance
|
||||
}
|
||||
|
||||
func (yih *YitIdHelper) SetIdGenerator(options *contract.IdGeneratorOptions) {
|
||||
yih.idGenInstance = NewDefaultIdGenerator(options)
|
||||
}
|
||||
|
||||
func (yih *YitIdHelper) NextId() uint64 {
|
||||
once.Do(func() {
|
||||
if yih.idGenInstance == nil {
|
||||
options := contract.NewIdGeneratorOptions(1)
|
||||
yih.idGenInstance = NewDefaultIdGenerator(options)
|
||||
}
|
||||
})
|
||||
|
||||
return yih.idGenInstance.NewLong()
|
||||
}
|
||||
@@ -1 +1,9 @@
|
||||
module "yitidgen"
|
||||
module yitidgen
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/onsi/ginkgo v1.15.2 // indirect
|
||||
github.com/onsi/gomega v1.11.0 // indirect
|
||||
)
|
||||
|
||||
82
Go/source/go.sum
Normal file
82
Go/source/go.sum
Normal file
@@ -0,0 +1,82 @@
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.15.2 h1:l77YT15o814C2qVL47NOyjV/6RbaP7kKdrvZnxQ3Org=
|
||||
github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
@@ -4,7 +4,7 @@
|
||||
* 代码修订:yitter
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package gen
|
||||
package idgen
|
||||
|
||||
import (
|
||||
"time"
|
||||
68
Go/source/idgen/YitIdHelper.go
Normal file
68
Go/source/idgen/YitIdHelper.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 版权属于:yitter(yitter@126.com)
|
||||
* 代码编辑:guoyahao
|
||||
* 代码修订:yitter
|
||||
* 开源地址:https://gitee.com/yitter/idgenerator
|
||||
*/
|
||||
package idgen
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"yitidgen/contract"
|
||||
)
|
||||
|
||||
//var yitIdHelper *YitIdHelper
|
||||
//var once sync.Once
|
||||
|
||||
var idGenerator *DefaultIdGenerator
|
||||
var singletonMutex sync.Mutex
|
||||
|
||||
type YitIdHelper struct {
|
||||
idGenInstance interface {
|
||||
NewLong() uint64
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//func GetIns() *YitIdHelper {
|
||||
// once.Do(func() {
|
||||
// yitIdHelper = &YitIdHelper{}
|
||||
// })
|
||||
// return yitIdHelper
|
||||
//}
|
||||
//
|
||||
//func (yih *YitIdHelper) GetIdGenInstance() interface{} {
|
||||
// return yih.idGenInstance
|
||||
//}
|
||||
//
|
||||
//func (yih *YitIdHelper) SetIdGenerator(options *contract.IdGeneratorOptions) {
|
||||
// yih.idGenInstance = NewDefaultIdGenerator(options)
|
||||
//}
|
||||
//
|
||||
//func (yih *YitIdHelper) NextId() uint64 {
|
||||
// once.Do(func() {
|
||||
// if yih.idGenInstance == nil {
|
||||
// options := contract.NewIdGeneratorOptions(1)
|
||||
// yih.idGenInstance = NewDefaultIdGenerator(options)
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// return yih.idGenInstance.NewLong()
|
||||
//}
|
||||
|
||||
func SetIdGenerator(options *contract.IdGeneratorOptions) {
|
||||
singletonMutex.Lock()
|
||||
idGenerator = NewDefaultIdGenerator(options)
|
||||
singletonMutex.Unlock()
|
||||
}
|
||||
|
||||
func NextId() uint64 {
|
||||
if idGenerator == nil {
|
||||
singletonMutex.Lock()
|
||||
options := contract.NewIdGeneratorOptions(1)
|
||||
idGenerator = NewDefaultIdGenerator(options)
|
||||
singletonMutex.Unlock()
|
||||
}
|
||||
|
||||
return idGenerator.NewLong()
|
||||
}
|
||||
67
Go/source/main.go
Normal file
67
Go/source/main.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"C"
|
||||
"fmt"
|
||||
"time"
|
||||
"yitidgen/contract"
|
||||
"yitidgen/idgen"
|
||||
"yitidgen/regworkerid"
|
||||
)
|
||||
|
||||
//export SetOptions
|
||||
func SetOptions(workerId uint16) {
|
||||
var options = contract.NewIdGeneratorOptions(workerId)
|
||||
idgen.SetIdGenerator(options)
|
||||
}
|
||||
|
||||
//export NextId
|
||||
func NextId() uint64 {
|
||||
return idgen.NextId()
|
||||
}
|
||||
|
||||
//export RegisterWorkerId
|
||||
func RegisterWorkerId(ip *C.char, port int, password *C.char, maxWorkerId int) int {
|
||||
return regworkerid.RegisterWorkerId(C.GoString(ip), port, C.GoString(password), maxWorkerId)
|
||||
}
|
||||
|
||||
//export UnRegisterWorkerId
|
||||
func UnRegisterWorkerId() {
|
||||
regworkerid.UnRegisterWorkerId()
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 方法一:直接采用默认方法生成一个Id
|
||||
fmt.Println("生成的Id:", idgen.NextId())
|
||||
|
||||
fmt.Println("生成的Id:", regworkerid.RegisterWorkerId("localhost", 6379, "", 4))
|
||||
|
||||
return
|
||||
// 方法二:自定义参数
|
||||
var options = contract.NewIdGeneratorOptions(1)
|
||||
options.WorkerIdBitLength = 6
|
||||
options.SeqBitLength = 6
|
||||
options.TopOverCostCount = 2000
|
||||
options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
|
||||
idgen.SetIdGenerator(options)
|
||||
|
||||
var genCount = 50000
|
||||
|
||||
for {
|
||||
var begin = time.Now().UnixNano() / 1e6
|
||||
for i := 0; i < genCount; i++ {
|
||||
idgen.NextId()
|
||||
}
|
||||
var end = time.Now().UnixNano() / 1e6
|
||||
|
||||
fmt.Println(end - begin)
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// go build -o target\yitidgengo.dll -buildmode=c-shared main.go
|
||||
|
||||
//var yid = idgen.YitIdHelper{}
|
||||
//yid.SetIdGenerator(options)
|
||||
//fmt.Println(yid.NextId())
|
||||
230
Go/source/regworkerid/reghelper.go
Normal file
230
Go/source/regworkerid/reghelper.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package regworkerid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-redis/redis"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Client *redis.Client
|
||||
|
||||
var _usingWorkerId int = -1
|
||||
var _maxWorkerId int = 0
|
||||
var _loopCount int = 0
|
||||
var _liftIndex int = -1
|
||||
var _workerIdLock sync.Mutex
|
||||
|
||||
const CurrentWidIndexKey string = "IdGen:WorkerId:Index"
|
||||
const WidKeyPrefix string = "IdGen:WorkerId:Value:"
|
||||
const WorkerIdFlag = "Y" // WorkerId 存储标记
|
||||
const WorkerIdLifeTimeSeconds = 15 // WorkerIdFlag 有效期(单位秒,最好是3的倍数)
|
||||
const Log = false
|
||||
|
||||
func UnRegisterWorkerId() {
|
||||
if _usingWorkerId < 0 {
|
||||
return
|
||||
}
|
||||
_workerIdLock.Lock()
|
||||
Client.Del(WidKeyPrefix + strconv.Itoa(_usingWorkerId))
|
||||
_usingWorkerId = -1
|
||||
_liftIndex = -1
|
||||
_workerIdLock.Unlock()
|
||||
}
|
||||
|
||||
func RegisterWorkerId(ip string, port int, password string, maxWorkerId int) int {
|
||||
// maxWorkerId不能小于0
|
||||
if maxWorkerId < 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
// 如果当前已注册过 WorkerId,则先注销,并终止先前的自动续期线程
|
||||
if _usingWorkerId > -1 {
|
||||
UnRegisterWorkerId()
|
||||
}
|
||||
|
||||
_maxWorkerId = maxWorkerId
|
||||
Client = redis.NewClient(&redis.Options{
|
||||
Addr: string(ip) + ":" + strconv.Itoa(port),
|
||||
PoolSize: 1000,
|
||||
ReadTimeout: time.Millisecond * time.Duration(100),
|
||||
WriteTimeout: time.Millisecond * time.Duration(100),
|
||||
IdleTimeout: time.Second * time.Duration(60),
|
||||
Password: password,
|
||||
})
|
||||
_, err := Client.Ping().Result()
|
||||
if err != nil {
|
||||
panic("init redis error")
|
||||
} else {
|
||||
if Log {
|
||||
fmt.Println("init redis ok")
|
||||
}
|
||||
}
|
||||
|
||||
_loopCount = 0
|
||||
return getNextWorkerId()
|
||||
}
|
||||
|
||||
func getNextWorkerId() int {
|
||||
// 获取当前 WorkerIdIndex
|
||||
// var currentId = int(Client.Incr(CurrentWidIndexKey).Val())
|
||||
r, err := Client.Incr(CurrentWidIndexKey).Result()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
currentId := int(r)
|
||||
if Log {
|
||||
fmt.Println("Begin currentId:" + strconv.Itoa(currentId))
|
||||
}
|
||||
|
||||
// 如果 Index 大于最大值,则重置
|
||||
if currentId > _maxWorkerId {
|
||||
if canReset() {
|
||||
// 当前应用获得重置 WorkerIdIndex 的权限
|
||||
setWorkerIdIndex(-1)
|
||||
endReset() // 此步有可能不被执行?
|
||||
_loopCount++
|
||||
// 超过一定次数,直接终止操作
|
||||
if _loopCount > 10 {
|
||||
return -1
|
||||
}
|
||||
|
||||
// if _loopCount > 2 {
|
||||
// 如果超过2个循环,则暂停1s
|
||||
time.Sleep(time.Duration(500*_loopCount) * time.Millisecond)
|
||||
//_loopCount = 0
|
||||
//}
|
||||
|
||||
if Log {
|
||||
fmt.Println("canReset loop")
|
||||
}
|
||||
|
||||
return getNextWorkerId()
|
||||
} else {
|
||||
// 如果有其它应用正在编辑,则本应用暂停1s后,再继续
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond)
|
||||
|
||||
if Log {
|
||||
fmt.Println("not canReset loop")
|
||||
}
|
||||
|
||||
return getNextWorkerId()
|
||||
}
|
||||
}
|
||||
|
||||
if Log {
|
||||
fmt.Println("currentId:" + strconv.Itoa(currentId))
|
||||
}
|
||||
|
||||
if isAvailable(currentId) {
|
||||
if Log {
|
||||
fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId))
|
||||
}
|
||||
|
||||
// 最新获得的 WorkerIdIndex,在 redis 中是可用状态
|
||||
setWorkerIdFlag(currentId)
|
||||
_usingWorkerId = currentId
|
||||
|
||||
// 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime)
|
||||
_liftIndex++
|
||||
go extendWorkerIdLifeTime(_liftIndex)
|
||||
|
||||
return currentId
|
||||
} else {
|
||||
if Log {
|
||||
fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId))
|
||||
}
|
||||
// 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex
|
||||
return getNextWorkerId()
|
||||
}
|
||||
}
|
||||
|
||||
func extendWorkerIdLifeTime(lifeIndex int) {
|
||||
var index = lifeIndex
|
||||
for {
|
||||
time.Sleep(time.Duration(WorkerIdLifeTimeSeconds/3) * time.Millisecond)
|
||||
|
||||
_workerIdLock.Lock()
|
||||
if index != _liftIndex {
|
||||
// 如果临时变量 index 不等于 全局变量 _liftIndex,表明全局状态被修改,当前线程可终止
|
||||
break
|
||||
}
|
||||
|
||||
// 已经被注销,则终止(此步是上一步的二次验证)
|
||||
if _usingWorkerId < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
extendWorkerIdFlag(_usingWorkerId)
|
||||
_workerIdLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func get(key string) (string, bool) {
|
||||
r, err := Client.Get(key).Result()
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
|
||||
func set(key string, val string, expTime int32) {
|
||||
Client.Set(key, val, time.Duration(expTime)*time.Second)
|
||||
}
|
||||
|
||||
func setWorkerIdIndex(val int) {
|
||||
Client.Set(CurrentWidIndexKey, val, 0)
|
||||
}
|
||||
|
||||
func setWorkerIdFlag(index int) {
|
||||
Client.Set(WidKeyPrefix+strconv.Itoa(index), WorkerIdFlag, time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
|
||||
}
|
||||
|
||||
func extendWorkerIdFlag(index int) {
|
||||
Client.Expire(WidKeyPrefix+strconv.Itoa(index), time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
|
||||
}
|
||||
|
||||
func canReset() bool {
|
||||
r, err := Client.Incr(WidKeyPrefix + "Edit").Result()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if Log {
|
||||
fmt.Println("canReset:" + string(r))
|
||||
}
|
||||
|
||||
return r != 1
|
||||
}
|
||||
|
||||
func endReset() {
|
||||
// Client.Set(WidKeyPrefix+"Edit", 0, time.Duration(2)*time.Second)
|
||||
Client.Set(WidKeyPrefix+"Edit", 0, 0)
|
||||
}
|
||||
|
||||
func getWorkerIdFlag(index int) (string, bool) {
|
||||
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
|
||||
func isAvailable(index int) bool {
|
||||
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
|
||||
|
||||
if Log {
|
||||
fmt.Println("XX isAvailable:" + r)
|
||||
fmt.Println("YY isAvailable:" + err.Error())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err.Error() == "redis: nil" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return r != WorkerIdFlag
|
||||
}
|
||||
BIN
Go/source/target/go_build_main_go.exe
Normal file
BIN
Go/source/target/go_build_main_go.exe
Normal file
Binary file not shown.
BIN
Go/source/target/main.dll
Normal file
BIN
Go/source/target/main.dll
Normal file
Binary file not shown.
75
Go/source/target/main.h
Normal file
75
Go/source/target/main.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) GoUint64 NextId();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
BIN
Go/source/target/yitidgen.dll
Normal file
BIN
Go/source/target/yitidgen.dll
Normal file
Binary file not shown.
75
Go/source/target/yitidgen.h
Normal file
75
Go/source/target/yitidgen.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) GoUint64 NextId();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
BIN
Go/source/target/yitidgengo.dll
Normal file
BIN
Go/source/target/yitidgengo.dll
Normal file
Binary file not shown.
78
Go/source/target/yitidgengo.h
Normal file
78
Go/source/target/yitidgengo.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) void SetOptions(GoUint16 workerId);
|
||||
extern __declspec(dllexport) GoUint64 NextId();
|
||||
extern __declspec(dllexport) GoInt RegisterWorkerId(char* ip, GoInt port, char* password, GoInt maxWorkerId);
|
||||
extern __declspec(dllexport) void UnRegisterWorkerId();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,43 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"C"
|
||||
"fmt"
|
||||
"time"
|
||||
"yitidgen/contract"
|
||||
"yitidgen/gen"
|
||||
)
|
||||
|
||||
|
||||
//export NextId
|
||||
func NextId() uint64{
|
||||
return gen.GetIns().NextId()
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 方法一:直接采用默认方法生成一个Id
|
||||
var yid = gen.YitIdHelper{}
|
||||
fmt.Println(yid.NextId())
|
||||
|
||||
// 方法二:自定义参数
|
||||
var options = contract.NewIdGeneratorOptions(1)
|
||||
//options.WorkerIdBitLength = 6
|
||||
//options.SeqBitLength = 6
|
||||
//options.TopOverCostCount = 2000
|
||||
//options.BaseTime = time.Date(2020, 2, 20, 2, 20, 2, 20, time.UTC).UnixNano() / 1e6
|
||||
yid.SetIdGenerator(options)
|
||||
|
||||
var times = 50000
|
||||
|
||||
for {
|
||||
var begin = time.Now().UnixNano() / 1e6
|
||||
for i := 0; i < times; i++ {
|
||||
yid.NextId()
|
||||
}
|
||||
var end = time.Now().UnixNano() / 1e6
|
||||
|
||||
fmt.Println(end - begin)
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user