DealyedOperationPurgatory是一个辅助类,用于管理DelayedOperation和处理到期的DelayedOperation,组件图如下:
一 核心字段
purgatoryName:String 表示DelayedOperationPurgatory的名字
timeoutTimer:Timer 表示SystemTimer,用于定时任务调度
brokerId:int 表示哪一个broker
purgeInterval:Int 表示清理时间间隔
watchersForKey:Pool[Any, Watchers] 用于管理DelayedOperation, key表示Wathers中的DelayedOperation关心的对象,value表示Watcher类型对象,是一个DelayedOperation的集合,底层使用LinkedList实现
removeWatchersLock:ReentrantReadWriteLock 对watchersForKey进行同步的读写锁操作
estimatedTotalOperations:AtomicInteger 表示该DelayedOperation
Purgatory中DelayedOperation个数
expirationReaper:ExpiredOperationReaper 表示线程对象,主要用于推进时间轮指针,另外主要是用于定期清理watchersForKey中已完成的DelayedOperation操作,清理条件根据purgeInterval指定
二 重要方法
2.1 Watcher重要方法
在Wacthers中,只有一个operation字段用于保存DelayedOperation延迟操作
# watch:添加DelayedOperation到队列中
def watch(t: T) {
operations.add(t)
}
# tryCompleteWatched:遍历operation队列,对于未完成的Delayed
Operation操纵执行safeTryComplete方法,对于已经完成的 Delayed
Operation进行删除,如果operation队列为空,则将Watcher从Delayed
OperationPurgatory的watchesForKey中删除
def tryCompleteWatched(): Int = {
var completed = 0
val iter = operations.iterator()
while (iter.hasNext) {// 遍历operation队列
val curr = iter.next()
if (curr.isCompleted) {
// 对于已经完成的的DeplayedOperation从operations队列中移除
iter.remove()
} else if (curr.safeTryComplete()) {// 调用safeTryComplete尝试完成延迟操作
iter.remove()
completed += 1
}
}
// 如果operations队列为空,则则将Watcher从 DelayedOperationPurgatory的watchesForKey中删除
if (operations.isEmpty)
removeKeyIfEmpty(key, this)
completed
}
# purgeCompleted: 如果延迟操作已经完成,则从队列中删除,如果operations队列为空,则则将Watcher从 DelayedOperationPurgatory的watchesForKey中删除
def purgeCompleted(): Int = {
var purged = 0
val iter = operations.iterator()
while (iter.hasNext) {// 遍历operation队列
val curr = iter.next()
if (curr.isCompleted) {// 如果延迟操作已经完成,则从队列中删除
iter.remove()
purged += 1
}
}
// 如果operations队列为空,则则将Watcher从 DelayedOperationPurgatory的watchesForKey中删除
if (operations.isEmpty)
removeKeyIfEmpty(key, this)
purged
}
# advanceClock:尝试推进当前时间轮的指针,并且更新watcher监控的延迟操作数量和清理operation队列里的延迟操作
def advanceClock(timeoutMs: Long) {
//尝试推进当前时间轮的指针,同时也会尝试推进上层时间轮的指针,随着当前时间轮的不断推进,上层时间轮指针早晚会被推进成功
timeoutTimer.advanceClock(timeoutMs)
// 如果已经完成的但仍然处于Watcher监控的DelayOperation的数量比purgeInterval还大
if (estimatedTotalOperations.get - delayed > purgeInterval) {
// 更新Watcher监控的DelayOperation的数量为时间轮里的任务数量
estimatedTotalOperations.getAndSet(delayed)
debug("Begin purging watch lists")
// 所有Watcher开始调用purgeCompleted方法进行删除已经完成的DelayedOperation操作
val purged = allWatchers.map(_.purgeCompleted()).sum
debug("Purged %d elements from watch lists.".format(purged))
}
}
2.2 DelayedOperationPurgatory重要方法
# tryCompleteElseWatch 主要是检测DelayedOperation是否完成,若未完成则添加到watchersForKey以及SystemtTimer中
def tryCompleteElseWatch(operation: T, watchKeys: Seq[Any]): Boolean = {
assert(watchKeys.nonEmpty, "The watch key list can't be empty")
// 尝试完成DelayedOperation操作
var isCompletedByMe = operation.safeTryComplete()
if (isCompletedByMe) // 如果已经完成直接返回
return true
var watchCreated = false
// 传入的key可能有多个,每一个key表示DelayedOperation关心的条件
for(key <- watchKeys) {
// 如果添加过程已经被其他线程完成,则放弃添加
if (operation.isCompleted)
return false
// 将DelayedOperation添加到对应的Watcher中
watchForOperation(key, operation)
// 增加estimatedTotalOperations数量值
if (!watchCreated) {
watchCreated = true
estimatedTotalOperations.incrementAndGet()
}
}
// 再次进行尝试完成,如果成功直接返回
isCompletedByMe = operation.safeTryComplete()
if (isCompletedByMe)
return true
// 如果DeplayedOperation没有完成,则将提交到SystemTimer
if (!operation.isCompleted) {
timeoutTimer.add(operation)
if (operation.isCompleted) {// 再次检测完成情况
// 如果已经完成,从SystemTimer中移除
operation.cancel()
}
}
false
}
# checkAndComplete:主要根据传入的key尝试执行对应的Watchers中的DelayedOperation,则通过调用Watcher#tryCompleteWatched实现
def checkAndComplete(key: Any): Int = {
val watchers = inReadLock(removeWatchersLock) { watchersForKey.get(key) }
if(watchers == null)
0
else
watchers.tryCompleteWatched()
}