设计模式之模板方法模式在kafka DelayedOperation中的应用

**模板方法模式定义:**定义一个操作中的算法框架,而将一些步骤延迟到子类当中实现,使得一个子类可以不改变算法结构而重定义该算法某些具体的步骤。
DelayedOperation: DelayedOperation是Kafka延迟任务部分代码中延迟任务的抽象基类。延迟操作用来实现Kafka中的一些特殊场景,例如在ack=all的情况下生产者向broker发送数据,由于数据需要在replica中进行同步,所以broker向生产者发送response需要延迟执行,这便是一个延迟操作。
DelayedOperation代码及具体方法含义:

abstract class DelayedOperation(override val delayMs: Long,
    lockOpt: Option[Lock] = None) extends TimerTask with Logging {
  //标致操作是否完成
  private val completed = new AtomicBoolean(false)
  //辅助保证多线程情况下的线程安全
  private val tryCompletePending = new AtomicBoolean(false)
  private[server] val lock: Lock = lockOpt.getOrElse(new ReentrantLock)

  /*
   * 强制进行延迟操作的算法结构(如果延迟操作没有完成,强制完成延迟操作)
   */
  def forceComplete(): Boolean = {
    if (completed.compareAndSet(false, true)) {
      // cancel the timeout timer
      cancel()
      onComplete()
      true
    } else {
      false
    }
  }

  /**
   * Check if the delayed operation is already completed
   */
  def isCompleted: Boolean = completed.get()
  
  def onExpiration(): Unit

  /**
   * 执行延迟操作,由子类实现
   */
  def onComplete(): Unit
 /**
   * 执行延迟操作,由子类实现
   */
  def tryComplete(): Boolean

 
  /**
   * 多线程场景下进行延迟操作的算法结构
   */
  private[server] def maybeTryComplete(): Boolean = {
    var retry = false
    var done = false
    do {
      if (lock.tryLock()) {
        try {
          tryCompletePending.set(false)
          done = tryComplete()
        } finally {
          lock.unlock()
        }
        retry = tryCompletePending.get()
      } else {
        retry = !tryCompletePending.getAndSet(true)
      }
    } while (!isCompleted && retry)
    done
  }

  override def run(): Unit = {
    if (forceComplete())
      onExpiration()
  }
}

在DelayedOperation的代码中通过maybeTryComplete方法定义了延迟操作的具体算法结构,但其中的步骤tryComplete方法并没有实现,原因在于maybeTryComplete的算法结构是不变的所有的延迟操作执行都是这个逻辑,但tryComplete的逻辑不是固定的,不同的延迟操作完成的逻辑不同。这种实现方法封装了不变的部分,扩展了(在子类)可变的部分,代码的可维护性、扩展性大大增强。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值