1 /* 2 * Make.org Core API 3 * Copyright (C) 2021 Make.org 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package org.make.api.technical 21 22 import akka.pattern.AskTimeoutException 23 24 import scala.concurrent.{ExecutionContext, Future} 25 26 object RetryableFuture { 27 28 @SuppressWarnings(Array("org.wartremover.warts.Recursion")) 29 def retry[T](future: () => Future[T], shouldRetry: Throwable => Boolean, times: Int = 3)( 30 implicit executionContext: ExecutionContext 31 ): Future[T] = { 32 future().recoverWith { error => 33 if (shouldRetry(error) && times > 0) { 34 retry(future, shouldRetry, times - 1) 35 } else { 36 Future.failed(error) 37 } 38 } 39 } 40 41 def retryOnAskTimeout[T](future: () => Future[T], times: Int = 3)( 42 implicit executionContext: ExecutionContext 43 ): Future[T] = { 44 retry(future, { 45 case _: AskTimeoutException => true 46 case _ => false 47 }, times) 48 } 49 50 }
| Line | Stmt Id | Pos | Tree | Symbol | Tests | Code |
|---|---|---|---|---|---|---|
| 32 | 19031 | 1121 - 1301 | ApplyToImplicitArgs | scala.concurrent.Future.recoverWith | org.make.api.technical.retryablefuturetest | future.apply().recoverWith[T](({ @SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[Throwable,scala.concurrent.Future[T]] with java.io.Serializable { def <init>(): <$anon: Throwable => scala.concurrent.Future[T]> = { $anonfun.super.<init>(); () }; final override def applyOrElse[A1 <: Throwable, B1 >: scala.concurrent.Future[T]](error: A1, default: A1 => B1): B1 = ((error.asInstanceOf[Throwable]: Throwable): Throwable @unchecked) match { case (defaultCase$ @ _) => if (shouldRetry.apply(error).&&(times.>(0))) RetryableFuture.this.retry[T](future, shouldRetry, times.-(1))(executionContext) else scala.concurrent.Future.failed[Nothing](error) case (defaultCase$ @ _) => default.apply(error) }; final def isDefinedAt(error: Throwable): Boolean = ((error.asInstanceOf[Throwable]: Throwable): Throwable @unchecked) match { case (defaultCase$ @ _) => true case (defaultCase$ @ _) => false } }; new $anonfun() }: PartialFunction[Throwable,scala.concurrent.Future[T]]))(executionContext) |
| 44 | 18717 | 1447 - 1561 | ApplyToImplicitArgs | org.make.api.technical.RetryableFuture.retry | RetryableFuture.this.retry[T](future, ((x0$1: Throwable) => x0$1 match { case (_: akka.pattern.AskTimeoutException) => true case _ => false }), times)(executionContext) |