| @@ -13,7 +13,7 @@ var _workerIdLock sync.Mutex | |||||
| var _usingWorkerId int = -1 // 当前已注册的WorkerId | var _usingWorkerId int = -1 // 当前已注册的WorkerId | ||||
| var _loopCount int = 0 // 循环数量 | var _loopCount int = 0 // 循环数量 | ||||
| var _liftIndex int = -1 // WorkerId本地生命时序(本地多次注册时,生命时序会不同) | |||||
| var _lifeIndex int = -1 // WorkerId本地生命时序(本地多次注册时,生命时序会不同) | |||||
| var _token int = -1 // WorkerId远程注册时用的token,将存储在 IdGen:WorkerId:Value:xx 的值中(本功能暂未启用) | var _token int = -1 // WorkerId远程注册时用的token,将存储在 IdGen:WorkerId:Value:xx 的值中(本功能暂未启用) | ||||
| var _WorkerIdLifeTimeSeconds = 15 // IdGen:WorkerId:Value:xx 的值在 redis 中的有效期(单位秒,最好是3的整数倍) | var _WorkerIdLifeTimeSeconds = 15 // IdGen:WorkerId:Value:xx 的值在 redis 中的有效期(单位秒,最好是3的整数倍) | ||||
| @@ -38,10 +38,11 @@ func UnRegisterWorkerId() { | |||||
| if _usingWorkerId < 0 { | if _usingWorkerId < 0 { | ||||
| return | return | ||||
| } | } | ||||
| _workerIdLock.Lock() | _workerIdLock.Lock() | ||||
| _client.Del(_WorkerIdValueKeyPrefix + strconv.Itoa(_usingWorkerId)) | _client.Del(_WorkerIdValueKeyPrefix + strconv.Itoa(_usingWorkerId)) | ||||
| _usingWorkerId = -1 | _usingWorkerId = -1 | ||||
| _liftIndex = -1 | |||||
| _lifeIndex = -1 | |||||
| _workerIdLock.Unlock() | _workerIdLock.Unlock() | ||||
| } | } | ||||
| @@ -85,13 +86,13 @@ func getNextWorkerId() int { | |||||
| return 0 | return 0 | ||||
| } | } | ||||
| currentId := int(r) | |||||
| candidateId := int(r) | |||||
| if _Log { | if _Log { | ||||
| fmt.Println("Begin currentId:" + strconv.Itoa(currentId)) | |||||
| fmt.Println("Begin candidateId:" + strconv.Itoa(candidateId)) | |||||
| } | } | ||||
| // 如果 currentId 大于最大值,则重置 | |||||
| if currentId > _MaxWorkerId { | |||||
| // 如果 candidateId 大于最大值,则重置 | |||||
| if candidateId > _MaxWorkerId { | |||||
| if canReset() { | if canReset() { | ||||
| // 当前应用获得重置 WorkerIdIndex 的权限 | // 当前应用获得重置 WorkerIdIndex 的权限 | ||||
| setWorkerIdIndex(-1) | setWorkerIdIndex(-1) | ||||
| @@ -124,27 +125,27 @@ func getNextWorkerId() int { | |||||
| } | } | ||||
| if _Log { | if _Log { | ||||
| fmt.Println("currentId:" + strconv.Itoa(currentId)) | |||||
| fmt.Println("candidateId:" + strconv.Itoa(candidateId)) | |||||
| } | } | ||||
| if isAvailable(currentId) { | |||||
| if isAvailable(candidateId) { | |||||
| if _Log { | if _Log { | ||||
| fmt.Println("AA: isAvailable:" + strconv.Itoa(currentId)) | |||||
| fmt.Println("AA: isAvailable:" + strconv.Itoa(candidateId)) | |||||
| } | } | ||||
| // 最新获得的 WorkerIdIndex,在 redis 中是可用状态 | // 最新获得的 WorkerIdIndex,在 redis 中是可用状态 | ||||
| setWorkerIdFlag(currentId) | |||||
| _usingWorkerId = currentId | |||||
| setWorkerIdFlag(candidateId) | |||||
| _usingWorkerId = candidateId | |||||
| _loopCount = 0 | _loopCount = 0 | ||||
| // 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 _WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime) | // 获取到可用 WorkerId 后,启用新线程,每隔 1/3个 _WorkerIdLifeTimeSeconds 时间,向服务器续期(延长一次 LifeTime) | ||||
| _liftIndex++ | |||||
| go extendWorkerIdLifeTime(_liftIndex) | |||||
| _lifeIndex++ | |||||
| go extendWorkerIdLifeTime(_lifeIndex) | |||||
| return currentId | |||||
| return candidateId | |||||
| } else { | } else { | ||||
| if _Log { | if _Log { | ||||
| fmt.Println("BB: not isAvailable:" + strconv.Itoa(currentId)) | |||||
| fmt.Println("BB: not isAvailable:" + strconv.Itoa(candidateId)) | |||||
| } | } | ||||
| // 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex | // 最新获得的 WorkerIdIndex,在 redis 中是不可用状态,则继续下一个 WorkerIdIndex | ||||
| return getNextWorkerId() | return getNextWorkerId() | ||||
| @@ -152,13 +153,17 @@ func getNextWorkerId() int { | |||||
| } | } | ||||
| func extendWorkerIdLifeTime(lifeIndex int) { | func extendWorkerIdLifeTime(lifeIndex int) { | ||||
| var index = lifeIndex | |||||
| var myLifeIndex = lifeIndex | |||||
| // 循环操作:间隔一定时间,刷新 WorkerId 在 redis 中的有效时间。 | |||||
| for { | for { | ||||
| time.Sleep(time.Duration(_WorkerIdLifeTimeSeconds/3) * time.Millisecond) | time.Sleep(time.Duration(_WorkerIdLifeTimeSeconds/3) * time.Millisecond) | ||||
| // 上锁操作,防止跟 UnRegisterWorkerId 操作重叠 | |||||
| _workerIdLock.Lock() | _workerIdLock.Lock() | ||||
| if index != _liftIndex { | |||||
| // 如果临时变量 index 不等于 全局变量 _liftIndex,表明全局状态被修改,当前线程可终止 | |||||
| // 如果临时变量 myLifeIndex 不等于 全局变量 _lifeIndex,表明全局状态被修改,当前线程可终止,不应继续操作 redis | |||||
| if myLifeIndex != _lifeIndex { | |||||
| break | break | ||||
| } | } | ||||
| @@ -167,7 +172,9 @@ func extendWorkerIdLifeTime(lifeIndex int) { | |||||
| break | break | ||||
| } | } | ||||
| // 延长 redis 数据有效期 | |||||
| extendWorkerIdFlag(_usingWorkerId) | extendWorkerIdFlag(_usingWorkerId) | ||||
| _workerIdLock.Unlock() | _workerIdLock.Unlock() | ||||
| } | } | ||||
| } | } | ||||
| @@ -236,5 +243,6 @@ func isAvailable(index int) bool { | |||||
| } | } | ||||
| return false | return false | ||||
| } | } | ||||
| return r != _WorkerIdFlag | return r != _WorkerIdFlag | ||||
| } | } | ||||