Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Created June 26, 2012 15:03
Show Gist options
  • Save j5ik2o/2996293 to your computer and use it in GitHub Desktop.
Save j5ik2o/2996293 to your computer and use it in GitHub Desktop.
リトライハンドラー
case class RetryException(throwables: List[Throwable]) extends Exception(throwables.toString())
object RetryUtil {
import scala.util.control.Exception.allCatch
def retry[T](retryLimit: Int)(f: => T): T =
retry(retryLimit, 0, classOf[Throwable])(f)
def retry[T](retryLimit: Int, retryInterval: Int)(f: => T): T =
retry(retryLimit, retryInterval, classOf[Throwable])(f)
def retry[T](retryLimit: Int, catchExceptionClasses: Class[_]*)(f: => T): T =
retry(retryLimit, 0, e => catchExceptionClasses.exists(_.isAssignableFrom(e.getClass)))(f)
def retry[T](retryLimit: Int, shouldCatch: Throwable => Boolean)(f: => T): T =
retry(retryLimit, 0, shouldCatch)(f)
def retry[T](retryLimit: Int, retryInterval: Int, catchExceptionClasses: Class[_]*)(f: => T): T =
retry(retryLimit, retryInterval, e => catchExceptionClasses.exists(_.isAssignableFrom(e.getClass)))(f)
def retry[T](retryLimit: Int, retryInterval: Int, shouldCatch: Throwable => Boolean)(f: => T): T = {
@annotation.tailrec
def retry0(errors: List[Throwable], f: => T): T = {
allCatch.either(f) match {
case Right(r) => r
case Left(e) =>
if (shouldCatch(e)) {
if (errors.size < retryLimit - 1) {
Thread.sleep(retryInterval)
retry0(e :: errors, f)
} else {
throw RetryException(e :: errors)
}
} else throw e
}
}
retry0(Nil, f)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment