An interesting approach to this might be to treat the timer as a resource using the scala-arm library.
You could provide your own implicit implementation of the Resource
type class for the timer so that it would automatically be stopped when it exits the managed scope or if an exception occurs. Ideally you could also increment your analytics counter in the resource implementation. This would completely eliminate the need for the try
/catch
/finally
. This would only work, however, if the couchbaseFailureMetricCounter
can somehow be referenced there. I would have to see the code or scaladocs for the metrics classes to understand whether that would make sense or not.
The concept would go something like this:
import resource._
override def get(key: String): Option[Any] =
managed(couchbaseMetricsTimer.time()) acquireAndGet { _ ⇒
Option(couchBaseClient.get(key))
}
And then, somewhere in the implicit scope, provide the Resource
implementation for the timer type, here assumed to be Timer
. The preferred place to put it would be in the companion object of the Timer
class (if you own the code for that class):
import scala.resource.Resource
object Timer {
implicit object TimerResource extends Resource[Timer] {
def close(timer) = timer.stop()
def closeAfterException(timer, throwable) = {
// not sure where this counter would come from, perhaps
// it could be mixed in or imported
couchbaseFailureMetricCounter.inc()
// super implementation also calls close
super.closeAfterException(timer, throwable)
}
}
}
couchbaseFailureMetricCounter.inc()
to increment failure counter whenever i get an exception. \$\endgroup\$