DelayedOperationPurgatory分析

来源:互联网 发布:食品安全数据库 编辑:程序博客网 时间:2024/06/06 02:15

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到队列中

defwatch(t:T) {
  operations.add(t)
}

 

# tryCompleteWatched:遍历operation队列,对于未完成的Delayed

Operation操纵执行safeTryComplete方法,对于已经完成的 Delayed

Operation进行删除,如果operation队列为空,则将Watcher从Delayed

OperationPurgatory的watchesForKey中删除

def tryCompleteWatched(): Int = {  var completed = val iter = operations.iterator()  while (iter.hasNext) {// 遍历operation队列    val curr = iter.next()    if (curr.isCompleted) {      // 对于已经完成的的DeplayedOperationoperations队列中移除      iter.remove()    } else if (curr.safeTryComplete()) {// 调用safeTryComplete尝试完成延迟操作      iter.remove()      completed += 1    }  }  // 如果operations队列为空,则则将Watcher DelayedOperationPurgatorywatchesForKey中删除  if (operations.isEmpty)    removeKeyIfEmpty(key, thiscompleted}

 

# purgeCompleted: 如果延迟操作已经完成,则从队列中删除,如果operations队列为空,则则将Watcher从 DelayedOperationPurgatory的watchesForKey中删除

def purgeCompleted(): Int = {  var purged = val iter = operations.iterator()  while (iter.hasNext) {// 遍历operation队列    val curr = iter.next()    if (curr.isCompleted) {// 如果延迟操作已经完成,则从队列中删除      iter.remove()      purged += 1    }  }  // 如果operations队列为空,则则将Watcher DelayedOperationPurgatorywatchesForKey中删除  if (operations.isEmpty)    removeKeyIfEmpty(key, thispurged}

 

# 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)    else    watchers.tryCompleteWatched()}

 


原创粉丝点击