Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stonegao/5590565 to your computer and use it in GitHub Desktop.
Save stonegao/5590565 to your computer and use it in GitHub Desktop.
package com.tumblr.fibr.service.filter
import com.tumblr.fibr.config.FilterConfig
import com.tumblr.fibr.tsdb.{TsdbRequest, TsdbResponse}
import com.google.common.cache.{Cache, CacheBuilder}
import com.twitter.finagle.Service
import com.twitter.util.Future
import java.util.concurrent.{Callable, TimeUnit}
/**
* If we see the same request within timeoutInSeconds, return the same response
*/
class DuplicateRequestFilter(override val filterConfig: FilterConfig,
timeoutInSeconds: Int = 300)
extends ServiceFilter
{
type TsdbService = Service[TsdbRequest, TsdbResponse]
val NotFoundInCache = mkStatName("query", "cache", "miss")
val FoundInCache = mkStatName("query", "cache", "hit")
val RequestedFromCache = mkStatName("query", "cache", "request")
private[this] val cache: Cache[TsdbRequest,Future[TsdbResponse]] = CacheBuilder.newBuilder()
.maximumSize(500)
.expireAfterAccess(timeoutInSeconds, TimeUnit.SECONDS)
.build()
override def apply(request: TsdbRequest, service: TsdbService): Future[TsdbResponse] = {
val wasPresent = cache.getIfPresent(request)
cache.get(request, new Callable[Future[TsdbResponse]] {
override def call: Future[TsdbResponse] = {
service(request)
}
}).ensure {
wasPresent match {
case null =>
Stats.incr(NotFoundInCache)
case o =>
Stats.incr(FoundInCache)
log.info("Found query in cache: %s".format(request.toString))
}
Stats.incr(RequestedFromCache)
}
}
val EvictedFromCache = mkStatName("query", "cache", "evict")
Stats.addGauge(EvictedFromCache) { cache.stats.evictionCount }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment