I have this sample code below. I don't want to block inside combinator resource.map
, so I put Await.result
inside Future
. But when I test this async recursion, I get concurrent.TimeoutException
from myRes
. What is the problem with the code? How do I fix it? Thank you.
// Code start here
val responses = Future.sequence(resource.map(params => asyncRecursionFunc(params)))
Await.result(responses, 5.minutes)
// My async function
def asyncRecursionFunc(params: sampleParameters, maxTryTimes: Int = 2, awaitTime: Int = 1): Future[(Seq[sample], String)] = {
val res: Future[GraphQLCluent.GraphQLResponse[SearchQueryResponse]] = client.query("gql", params).result
Future {
val myRes: GraphQLCluent.GraphQLResponse[SearchQueryResponse] = Await.result(res, 2.minutes)
val myValue: Seq[sample] = myRes.right.toSeq.flatmap(res => res)
if( !myValue.isEmpty || maxTryTimes <= 0 ){
(myValue, "stringMessage")
}
else{
Await.result(asyncRecursionFunc(params, maxTryTimes - 1, awaitTime 1), (2*(awaitTime 1)).minutes)
}
}
}
CodePudding user response:
Yeah, you should use flatMap
.
Await
is bad even inside a Future
(in some way, it is actually worse).
It is likely what is causing your immediate problem too (first few queries exhaust all the threads in the pool, and then Await
blocks forever).
Try doing it in a truly asynchronous way:
def doQuery(params: Foo, maxTries: Int) = client.query("gql", params).result.flatMap {
case Right(r) if r.nonEmpty => Future.successful(r -> "stringmessage")
case _ if maxTries == 1 => Future.successful(Nil -> "stringmessage")
case _ => doQuery(params, maxTries-1)
}