Skip to content

Instantly share code, notes, and snippets.

@ogatatsu
Forked from j5ik2o/gist:2996293
Created June 27, 2012 11:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ogatatsu/3003402 to your computer and use it in GitHub Desktop.
Save ogatatsu/3003402 to your computer and use it in GitHub Desktop.
リトライハンドラー 魔改造
try {
  val res = retry(...) {
    ...
  }
} catch {
  case RetryException(es) => ...
}

じゃなく

val res = retry(...) {
  ...
} `catch` {
  case es =>
}

と書けるように魔改造してみた

object RetryUtil {
import scala.util.control.Exception.allCatch
case class RetryResult[T](e: Either[List[Throwable], T]) {
def `catch`(f: List[Throwable] => T): T = e match {
case Right(r) => r
case Left(l) => f(l)
}
}
def retry[T](retryLimit: Int)(f: => T): RetryResult[T] =
retry(retryLimit, 0, classOf[Throwable])(f)
def retry[T](retryLimit: Int, retryInterval: Int)(f: => T): RetryResult[T] =
retry(retryLimit, retryInterval, classOf[Throwable])(f)
def retry[T](retryLimit: Int, catchExceptionClasses: Class[_]*)(f: => T): RetryResult[T] =
retry(retryLimit, 0, e => catchExceptionClasses.exists(_.isAssignableFrom(e.getClass)))(f)
def retry[T](retryLimit: Int, shouldCatch: Throwable => Boolean)(f: => T): RetryResult[T] =
retry(retryLimit, 0, shouldCatch)(f)
def retry[T](retryLimit: Int, retryInterval: Int, catchExceptionClasses: Class[_]*)(f: => T): RetryResult[T] =
retry(retryLimit, retryInterval, e => catchExceptionClasses.exists(_.isAssignableFrom(e.getClass)))(f)
def retry[T](retryLimit: Int, retryInterval: Int, shouldCatch: Throwable => Boolean)(f: => T): RetryResult[T] = {
@annotation.tailrec
def retry0(errors: List[Throwable], f: => T): RetryResult[T] = {
allCatch.either(f) match {
case Right(r) => RetryResult(Right(r))
case Left(e) =>
if (shouldCatch(e)) {
if (errors.size < retryLimit - 1) {
Thread.sleep(retryInterval)
retry0(e :: errors, f)
} else {
RetryResult(Left(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