DelayedOperationPurgatory分析

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) {
      // 对于已经完成的的DeplayedOperationoperations队列中移除
      iter.remove()
    } else if (curr.safeTryComplete()) {// 调用safeTryComplete尝试完成延迟操作
      iter.remove()
      completed += 1
    }
  }
  // 如果operations队列为空,则则将Watcher DelayedOperationPurgatorywatchesForKey中删除
  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 DelayedOperationPurgatorywatchesForKey中删除
  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()
}

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值