问题
I have created a graph to paralellise two flows with the same input. The flows produce Future[Option[Entity]]. If flowA fails I would like to return a Future[None] but the recover does not seem to be called
val graph: Flow[Input, (Future[Option[Entity]], Future[Option[Entity]]), NotUsed] = Flow.fromGraph(GraphDSL.create() { implicit builder =>
import GraphDSL.Implicits._
val broadcast = builder.add(Broadcast[Input](2))
val zip = builder.add(Zip[Future[Option[Entity]], Future[Option[Entity]]])
val flowAwithRecovery = flowA.recover{ case t: Throwable =>
logger.error(t, "Error retrieving output from flowA. Resuming without them.")
Future.successful(None)
}
broadcast.out(0) ~> flowAwithRecovery ~> zip.in0
broadcast.out(1) ~> flowB ~> zip.in1
FlowShape(broadcast.in, zip.out)
})
When I run the graph and flowA returns a Failed Future the recover does not get executed. As a workaround I am recovering the Future at the end of the processing but I would like to put this kind of logic when I design the graph.
回答1:
The recover
combinator comes into play when an exception has been propagated from upstream.
A Future.failed
is not an exception, but a valid element.
You would need something like
flowA.map(_.recover{ case t: Throwable =>
logger.error(t, "Error retrieving output from flowA. Resuming without them.")
None
})
On a different note, do you really need to pass around Future
s in your flows? You're probably better off using mapAsync
when building flowA
and flowB
and have them produce just Option[Entity]
.
来源:https://stackoverflow.com/questions/41833742/akka-stream-graph-recover-issue