Browse Source

auto commit

tags/v1.0.0
yitter 4 years ago
parent
commit
414e9a58e8
4 changed files with 74 additions and 55 deletions
  1. +11
    -3
      Go/source/main.go
  2. +56
    -50
      Go/source/regworkerid/reghelper.go
  3. BIN
      Go/source/target/yitidgengo.dll
  4. +7
    -2
      Go/source/target/yitidgengo.h

+ 11
- 3
Go/source/main.go View File

@@ -9,32 +9,40 @@ import (
"yitidgen/regworkerid" "yitidgen/regworkerid"
) )


//export SetOptions
///export SetOptions
func SetOptions(workerId uint16) { func SetOptions(workerId uint16) {
var options = contract.NewIdGeneratorOptions(workerId) var options = contract.NewIdGeneratorOptions(workerId)
idgen.SetIdGenerator(options) idgen.SetIdGenerator(options)
} }


//export NextId
///export NextId
func NextId() uint64 { func NextId() uint64 {
return idgen.NextId() return idgen.NextId()
} }


// 注册一个新的WorkerId
//export RegisterWorkerId //export RegisterWorkerId
func RegisterWorkerId(ip *C.char, port int, password *C.char, maxWorkerId int) int { func RegisterWorkerId(ip *C.char, port int, password *C.char, maxWorkerId int) int {
return regworkerid.RegisterWorkerId(C.GoString(ip), port, C.GoString(password), maxWorkerId) return regworkerid.RegisterWorkerId(C.GoString(ip), port, C.GoString(password), maxWorkerId)
} }


// 注销WorkerId
//export UnRegisterWorkerId //export UnRegisterWorkerId
func UnRegisterWorkerId() { func UnRegisterWorkerId() {
regworkerid.UnRegisterWorkerId() regworkerid.UnRegisterWorkerId()
} }


// 检查本地WorkerId是否有效
//export ValidateLocalWorkerId
func ValidateLocalWorkerId(workerId int) bool {
return regworkerid.ValidateLocalWorkerId(workerId)
}

func main() { func main() {
// 方法一:直接采用默认方法生成一个Id // 方法一:直接采用默认方法生成一个Id
fmt.Println("生成的Id:", idgen.NextId()) fmt.Println("生成的Id:", idgen.NextId())


fmt.Println("生成的Id:", regworkerid.RegisterWorkerId("localhost", 6379, "", 4))
fmt.Println("注册的WorkerId:", regworkerid.RegisterWorkerId("localhost", 6379, "", 4))


return return
// 方法二:自定义参数 // 方法二:自定义参数


+ 56
- 50
Go/source/regworkerid/reghelper.go View File

@@ -8,26 +8,34 @@ import (
"time" "time"
) )


var Client *redis.Client

var _usingWorkerId int = -1
var _maxWorkerId int = 0
var _loopCount int = 0
var _liftIndex int = -1
var _client *redis.Client
var _workerIdLock sync.Mutex 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
var _usingWorkerId int = -1 // 当前已注册的WorkerId
var _loopCount int = 0 // 循环数量
var _liftIndex int = -1 // WorkerId本地生命时序(本地多次注册时,生命时序会不同)
var _token int = -1 // WorkerId远程注册时用的token,将存储在 IdGen:WorkerId:Value:xx 的值中(本功能暂未启用)

var _WorkerIdLifeTimeSeconds = 15 // IdGen:WorkerId:Value:xx 的值在 redis 中的有效期(单位秒,最好是3的整数倍)
var _MaxLoopCount = 10 // 最大循环次数(无可用WorkerId时循环查找)
var _SleepMillisecondEveryLoop = 200 // 每次循环后,暂停时间
var _MaxWorkerId int = 0 // 最大WorkerId值,超过此值从0开始

const _WorkerIdIndexKey string = "IdGen:WorkerId:Index" // redis 中的key
const _WorkerIdValueKeyPrefix string = "IdGen:WorkerId:Value:" // redis 中的key
const _WorkerIdFlag = "Y" // IdGen:WorkerId:Value:xx 的值(将来可用 _token 替代)
const _Log = false // 是否输出日志

func ValidateLocalWorkerId(workerId int) bool {
return workerId == _usingWorkerId
}


func UnRegisterWorkerId() { func UnRegisterWorkerId() {
if _usingWorkerId < 0 { if _usingWorkerId < 0 {
return return
} }
_workerIdLock.Lock() _workerIdLock.Lock()
Client.Del(WidKeyPrefix + strconv.Itoa(_usingWorkerId))
_client.Del(_WorkerIdValueKeyPrefix + strconv.Itoa(_usingWorkerId))
_usingWorkerId = -1 _usingWorkerId = -1
_liftIndex = -1 _liftIndex = -1
_workerIdLock.Unlock() _workerIdLock.Unlock()
@@ -44,20 +52,20 @@ func RegisterWorkerId(ip string, port int, password string, maxWorkerId int) int
UnRegisterWorkerId() UnRegisterWorkerId()
} }


_maxWorkerId = maxWorkerId
Client = redis.NewClient(&redis.Options{
Addr: string(ip) + ":" + strconv.Itoa(port),
_MaxWorkerId = maxWorkerId
_client = redis.NewClient(&redis.Options{
Addr: ip + ":" + strconv.Itoa(port),
PoolSize: 1000, PoolSize: 1000,
ReadTimeout: time.Millisecond * time.Duration(100), ReadTimeout: time.Millisecond * time.Duration(100),
WriteTimeout: time.Millisecond * time.Duration(100), WriteTimeout: time.Millisecond * time.Duration(100),
IdleTimeout: time.Second * time.Duration(60), IdleTimeout: time.Second * time.Duration(60),
Password: password, Password: password,
}) })
_, err := Client.Ping().Result()
_, err := _client.Ping().Result()
if err != nil { if err != nil {
panic("init redis error") panic("init redis error")
} else { } else {
if Log {
if _Log {
fmt.Println("init redis ok") fmt.Println("init redis ok")
} }
} }
@@ -68,45 +76,42 @@ func RegisterWorkerId(ip string, port int, password string, maxWorkerId int) int


func getNextWorkerId() int { func getNextWorkerId() int {
// 获取当前 WorkerIdIndex // 获取当前 WorkerIdIndex
// var currentId = int(Client.Incr(CurrentWidIndexKey).Val())
r, err := Client.Incr(CurrentWidIndexKey).Result()
r, err := _client.Incr(_WorkerIdIndexKey).Result()
if err != nil { if err != nil {
return 0 return 0
} }


currentId := int(r) currentId := int(r)
if Log {
if _Log {
fmt.Println("Begin currentId:" + strconv.Itoa(currentId)) fmt.Println("Begin currentId:" + strconv.Itoa(currentId))
} }


// 如果 Index 大于最大值,则重置
if currentId > _maxWorkerId {
// 如果 currentId 大于最大值,则重置
if currentId > _MaxWorkerId {
if canReset() { if canReset() {
// 当前应用获得重置 WorkerIdIndex 的权限 // 当前应用获得重置 WorkerIdIndex 的权限
setWorkerIdIndex(-1) setWorkerIdIndex(-1)
endReset() // 此步有可能不被执行? endReset() // 此步有可能不被执行?
_loopCount++ _loopCount++
// 超过一定次数,直接终止操作 // 超过一定次数,直接终止操作
if _loopCount > 10 {
if _loopCount > _MaxLoopCount {
_loopCount = 0
return -1 return -1
} }


// if _loopCount > 2 {
// 如果超过2个循环,则暂停1s
time.Sleep(time.Duration(500*_loopCount) * time.Millisecond)
//_loopCount = 0
//}
// 每次一个大循环后,暂停一些时间
time.Sleep(time.Duration(_SleepMillisecondEveryLoop*_loopCount) * time.Millisecond)


if Log {
if _Log {
fmt.Println("canReset loop") fmt.Println("canReset loop")
} }


return getNextWorkerId() return getNextWorkerId()
} else { } else {
// 如果有其它应用正在编辑,则本应用暂停1s后,再继续
time.Sleep(time.Duration(1000) * time.Millisecond)
// 如果有其它应用正在编辑,则本应用暂停200ms后,再继续
time.Sleep(time.Duration(200) * time.Millisecond)


if Log {
if _Log {
fmt.Println("not canReset loop") fmt.Println("not canReset loop")
} }


@@ -114,26 +119,27 @@ func getNextWorkerId() int {
} }
} }


if Log {
if _Log {
fmt.Println("currentId:" + strconv.Itoa(currentId)) fmt.Println("currentId:" + strconv.Itoa(currentId))
} }


if isAvailable(currentId) { if isAvailable(currentId) {
if Log {
if _Log {
fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId)) fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId))
} }


// 最新获得的 WorkerIdIndex,在 redis 中是可用状态 // 最新获得的 WorkerIdIndex,在 redis 中是可用状态
setWorkerIdFlag(currentId) setWorkerIdFlag(currentId)
_usingWorkerId = currentId _usingWorkerId = currentId
_loopCount = 0


// 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime)
// 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 _WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime)
_liftIndex++ _liftIndex++
go extendWorkerIdLifeTime(_liftIndex) go extendWorkerIdLifeTime(_liftIndex)


return currentId return currentId
} else { } else {
if Log {
if _Log {
fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId)) fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId))
} }
// 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex // 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex
@@ -144,7 +150,7 @@ func getNextWorkerId() int {
func extendWorkerIdLifeTime(lifeIndex int) { func extendWorkerIdLifeTime(lifeIndex int) {
var index = lifeIndex var index = lifeIndex
for { for {
time.Sleep(time.Duration(WorkerIdLifeTimeSeconds/3) * time.Millisecond)
time.Sleep(time.Duration(_WorkerIdLifeTimeSeconds/3) * time.Millisecond)


_workerIdLock.Lock() _workerIdLock.Lock()
if index != _liftIndex { if index != _liftIndex {
@@ -163,7 +169,7 @@ func extendWorkerIdLifeTime(lifeIndex int) {
} }


func get(key string) (string, bool) { func get(key string) (string, bool) {
r, err := Client.Get(key).Result()
r, err := _client.Get(key).Result()
if err != nil { if err != nil {
return "", false return "", false
} }
@@ -171,28 +177,28 @@ func get(key string) (string, bool) {
} }


func set(key string, val string, expTime int32) { func set(key string, val string, expTime int32) {
Client.Set(key, val, time.Duration(expTime)*time.Second)
_client.Set(key, val, time.Duration(expTime)*time.Second)
} }


func setWorkerIdIndex(val int) { func setWorkerIdIndex(val int) {
Client.Set(CurrentWidIndexKey, val, 0)
_client.Set(_WorkerIdIndexKey, val, 0)
} }


func setWorkerIdFlag(index int) { func setWorkerIdFlag(index int) {
Client.Set(WidKeyPrefix+strconv.Itoa(index), WorkerIdFlag, time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
_client.Set(_WorkerIdValueKeyPrefix+strconv.Itoa(index), _WorkerIdFlag, time.Duration(_WorkerIdLifeTimeSeconds)*time.Second)
} }


func extendWorkerIdFlag(index int) { func extendWorkerIdFlag(index int) {
Client.Expire(WidKeyPrefix+strconv.Itoa(index), time.Duration(WorkerIdLifeTimeSeconds)*time.Second)
_client.Expire(_WorkerIdValueKeyPrefix+strconv.Itoa(index), time.Duration(_WorkerIdLifeTimeSeconds)*time.Second)
} }


func canReset() bool { func canReset() bool {
r, err := Client.Incr(WidKeyPrefix + "Edit").Result()
r, err := _client.Incr(_WorkerIdValueKeyPrefix + "Edit").Result()
if err != nil { if err != nil {
return false return false
} }


if Log {
if _Log {
fmt.Println("canReset:" + string(r)) fmt.Println("canReset:" + string(r))
} }


@@ -200,12 +206,12 @@ func canReset() bool {
} }


func endReset() { func endReset() {
// Client.Set(WidKeyPrefix+"Edit", 0, time.Duration(2)*time.Second)
Client.Set(WidKeyPrefix+"Edit", 0, 0)
// _client.Set(_WorkerIdValueKeyPrefix+"Edit", 0, time.Duration(2)*time.Second)
_client.Set(_WorkerIdValueKeyPrefix+"Edit", 0, 0)
} }


func getWorkerIdFlag(index int) (string, bool) { func getWorkerIdFlag(index int) (string, bool) {
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
r, err := _client.Get(_WorkerIdValueKeyPrefix + strconv.Itoa(index)).Result()
if err != nil { if err != nil {
return "", false return "", false
} }
@@ -213,9 +219,9 @@ func getWorkerIdFlag(index int) (string, bool) {
} }


func isAvailable(index int) bool { func isAvailable(index int) bool {
r, err := Client.Get(WidKeyPrefix + strconv.Itoa(index)).Result()
r, err := _client.Get(_WorkerIdValueKeyPrefix + strconv.Itoa(index)).Result()


if Log {
if _Log {
fmt.Println("XX isAvailable:" + r) fmt.Println("XX isAvailable:" + r)
fmt.Println("YY isAvailable:" + err.Error()) fmt.Println("YY isAvailable:" + err.Error())
} }
@@ -226,5 +232,5 @@ func isAvailable(index int) bool {
} }
return false return false
} }
return r != WorkerIdFlag
return r != _WorkerIdFlag
} }

BIN
Go/source/target/yitidgengo.dll View File


+ 7
- 2
Go/source/target/yitidgengo.h View File

@@ -68,11 +68,16 @@ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
extern "C" { extern "C" {
#endif #endif


extern __declspec(dllexport) void SetOptions(GoUint16 workerId);
extern __declspec(dllexport) GoUint64 NextId();
// 注册一个新的WorkerId
extern __declspec(dllexport) GoInt RegisterWorkerId(char* ip, GoInt port, char* password, GoInt maxWorkerId); extern __declspec(dllexport) GoInt RegisterWorkerId(char* ip, GoInt port, char* password, GoInt maxWorkerId);

// 注销WorkerId
extern __declspec(dllexport) void UnRegisterWorkerId(); extern __declspec(dllexport) void UnRegisterWorkerId();


// 检查本地WorkerId是否有效
extern __declspec(dllexport) GoUint8 ValidateLocalWorkerId(GoInt workerId);

#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

Loading…
Cancel
Save