All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finatra.thrift.routing.ThriftWarmup.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finatra.thrift.routing

import com.twitter.finatra.thrift.internal.ThriftMethodService
import com.twitter.finatra.thrift.utils.ThriftMethodUtils._
import com.twitter.finatra.utils.FuturePools
import com.twitter.inject.Logging
import com.twitter.scrooge.ThriftMethod
import com.twitter.util.Await
import javax.inject.Inject

class ThriftWarmup @Inject()(
  router: ThriftRouter)
  extends Logging {

  /* Use a FuturePool to avoid getting a ConstFuture from Future.apply(...) */
  private val pool = FuturePools.fixedPool("Thrift Warmup", 1)

  /* Public */

  /**
    * Send a request to warmup services that are not yet externally receiving traffic.
    *
    * @param method - [[com.twitter.scrooge.ThriftMethod]] to send request through
    * @param args - [[com.twitter.scrooge.ThriftMethod]].Args to send
    * @param times - number of times to send the request
    * @param responseCallback - callback called for every response where assertions can be made. NOTE: be aware that
    *                         failed assertions that throws Exceptions could prevent a server from restarting. This is
    *                         generally when dependent services are unresponsive causing the warm-up request(s) to fail.
    *                         As such, you should wrap your warm-up calls in these situations in a try/catch {}.
    * @tparam M - type of the [[com.twitter.scrooge.ThriftMethod]]
    */
  def send[M <: ThriftMethod](
    method: M,
    args: M#Args,
    times: Int = 1)(responseCallback: M#Result => Unit = unitFunction _): Unit = {

    for (i <- 1 to times) {
      time(s"Warmup ${prettyStr(method)} completed in %sms.") {
        val response = executeRequest(method, args)
        responseCallback(response)
      }
    }
  }

  def close() = {
    pool.executor.shutdownNow()
  }

  /* Private */

  private def executeRequest[M <: ThriftMethod](
    method: M,
    args: M#Args): M#Result = {

    val response = pool {
      info(s"Warmup ${prettyStr(method)}")
      val service = router.methods(method).asInstanceOf[ThriftMethodService[M#Args, M#Result]]
      service(args)
    }.flatten

    Await.result(response)
  }

  /**
    * Function curried as the default arg for the responseCallback: M#Result => Unit parameter.
    * @param a - [[AnyRef]]
    * @return Unit
    */
  private def unitFunction(a: AnyRef): Unit = ()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy