Any way out for sustaining a tail recursion once you go concurrent?
@tailrec // and we use an accumulator parameter for enabling that
def impl(
apiCall:HttpRequest = initialApiCall,
soFarResult: List[JsValue] = List())
: Future[List[JsValue]] = {
nonBlockingHttp(apiCall) flatMap { response =>
if (!response.isSuccess)
throw new Exception(s"""api call failed - have we been rate limited? failure details: \n$response""")
val asJson: JsValue = Json.parse(response.body) //println(Json.prettyPrint(asJson))
val headers = response.headers
val linkHeaders = parseGithubLinkHeader(headers("Link"))
println(linkHeaders)
val projects = (asJson \ "items")
.as[JsArray]
.as[List[JsValue]]
val result = soFarResult ++ projects
if (linkHeaders("next") == linkHeaders("last")) Future { result }
else impl(Http(linkHeaders("next")), result)
}
}
Of course, this yields
could not optimize @tailrec annotated method impl: it contains a recursive call not in tail position
as the flatMap
is the last call made, not the recursive call to impl
at the tail of flatMap
.