-
scala 에서 retry 구현하기scala/basic 2021. 11. 25. 18:11
문제
cats-effect 나 zio 등의 functional library 를 사용하면, 이미 구현되어 있는 retry 를 쉽게 사용할 수 있다. 혹은 retry library 를 활용할 수도 있다. 간단하게 쓸수 있도록 scala 표준 라이브러리만을 사용해 retry 를 구현해 보자. stackoverflow 를 참고할 수 있다.
코드
import scala.annotation.tailrec import scala.util.{Failure, Success, Try} object Util { @tailrec def retry[T](n: Int)(f: => T): Try[T] = if (n < 0) { Failure(new Exception(s"$n must be greater or equal to 0")) } else if (n == 0) { Try(f) } else { Try(f) match { case Success(value) => Success(value) case Failure(_) => if (n == 1) Try(f) else retry(n - 1)(f) } } }
AI 코드
import scala.concurrent.{Future, ExecutionContext} import scala.concurrent.duration._ import scala.util.{Failure, Success} import java.util.concurrent.Executors object RetryUtil { def retry[T](block: => Future[T], maxRetries: Int, delay: FiniteDuration) (implicit ec: ExecutionContext): Future[T] = { block.recoverWith { case _ if maxRetries > 0 => println(s"Retrying... attempts left: $maxRetries") Thread.sleep(delay.toMillis) retry(block, maxRetries - 1, delay) } } } // 사용 예제 object Main extends App { implicit val ec: ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(4)) def unreliableOperation: Future[Int] = Future { val random = scala.util.Random val value = random.nextInt(10) if (value < 8) throw new RuntimeException("Failed operation") else value } val result = RetryUtil.retry(unreliableOperation, 5, 2.seconds) result.onComplete { case Success(value) => println(s"Operation succeeded with value: $value") case Failure(exception) => println(s"Operation failed after retries: ${exception.getMessage}") } }
'scala > basic' 카테고리의 다른 글
java callback 을 scala Future 로 바꾸기 (0) 2022.07.16 sealed trait typeclass (0) 2022.03.29 scala enumeratum enum 사용하기 (0) 2021.11.13 Variance 문제 (3) 2021.10.22 apache poi 를 사용해 scala 에서 Excel 파일 읽기 (0) 2021.10.14