2017-03-23 23 views
1

我想實現一個代碼,它向外部REST端點發出請求,當該端點返回404時,它應該在有限時間內重試。用Akka處理HttpResponse 404上的重試邏輯http

HttpRequest中是一樣的東西

val responseFuture = Http().singleRequest(HttpRequest(method = requestMethod, 
    uri = url, 
    entity = HttpEntity(requestBody).withContentType(ContentTypes.`application/json`) 
)) 

,響應也被處理

responseFuture.onComplete { 
    case Success(r) => 
     if (r.status.isFailure()) Future.failed(new Exception("request failed with status 404")) 
     else r 
    case Failure(e) => throw e 
} 

我重試邏輯是:

def retryFuture[T](retries: Int, delay: FiniteDuration = 1.second)(fn: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { 
    fn.recoverWith { 
     case _ if retries > 0 => after(delay, s)(retryFuture(retries - 1, delay)(fn)) 
    } 
} 

問題是,當端點返回404,它來作爲SUCCESS(HttpResponse(404,...),所以重試不起作用。任何人都可以指出什麼CA要解決這個問題嗎?

回答

0

您應該將responseFuture定義爲def而不是val,以便能夠多次運行。

然後你只需要做responseFuture.filter(_.status.isSuccess())在404返回代碼(實際上在所有的錯誤代碼)上有一個Future.failed

您現在可以對此使用恢復策略。

0

onComplete不會改變未來的成敗;實際上,該函數的返回值被丟棄。相反,要麼在onComplete中執行重試,要麼使用transform獲取新的失敗的Future,前提是它是404,然後是recoverWith