Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Forked from xuwei-k/not_tailrec.scala
Created July 4, 2012 17:31
Show Gist options
  • Save gakuzzzz/3048489 to your computer and use it in GitHub Desktop.
Save gakuzzzz/3048489 to your computer and use it in GitHub Desktop.
リトライハンドラーの殴り書き
  • 1秒後, 5秒後, 15秒後, 60秒後 みたいなリトライがしたかったので interval に Stream[Int] を渡せるようにしてみた。
  • 無限 Stream 渡したら無限 retry もできるね。
import scala.util.control.Exception.allCatch
object RetryUtil {
case class RetryException(throwables: List[Throwable]) extends Exception
def retry[T](retryLimit: Int, retryInterval: Int, shouldCatch: Throwable => Boolean)(f: => T): T =
retry(Stream.fill(retryLimit)(retryInterval), shouldCatch)(f)
def retry[T](intervals: Stream[Int], shouldCatch: Throwable => Boolean)(f: => T): T = {
@annotation.tailrec
def _retry(_intervals: Stream[Int], errors: List[Throwable]): T = {
allCatch.either(f) match {
case Right(r) => r
case Left(e) =>
if (shouldCatch(e)) {
_intervals match {
case head #:: tail =>
Thread.sleep(head)
_retry(tail, e :: errors)
case _ => throw RetryException(e :: errors)
}
} else throw e
}
}
_retry(intervals, Nil)
}
}
scala> RetryUtil.retry(1000 #:: 3000 #:: 10000 #:: Stream.empty[Int], {_ => true}) {
| println(new java.util.Date)
| throw new RuntimeException("hoge")
| }
Thu Jul 05 02:58:24 JST 2012
Thu Jul 05 02:58:25 JST 2012
Thu Jul 05 02:58:28 JST 2012
Thu Jul 05 02:58:38 JST 2012
RetryUtil$RetryException
at RetryUtil$._retry$1(<console>:30)
at RetryUtil$.retry(<console>:35)
at .<init>(<console>:14)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:722)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment