Consider this simple stream:
Source(1 to 5)
.mapAsync(1) { i =>
if (i % 3 == 0) Future.failed(new Exception("I don't like 3"))
else Future.successful(i)
}
.withAttributes(
ActorAttributes.supervisionStrategy(Supervision.restartingDecider)
)
.runForeach(i => println(s"#$i"))
This actually prints
#1
#2
#4
Which is the same as with the resume strategy. I would expect the stream to restart after the failed future with the following output
#1
#2
#1
#2
...
Question 1: the difference between resume
and restart
is that - with the latter - the failing stage is restarted, losing all accumulated internal state. (See docs for reference).
In your case, you have a mapAsync
stage with parallelism 1, so you effectively will never have any accumulated state. This results in resume
and restart
being equivalent in behaviour.
Question 2: The semantic of supervision strategies in Akka streams are related to the specific stage that fails. A failed stage simply has no way to replay the elements that flowed in the past, as they are already gone - i.e. not held anywhere. No supervision strategy can give you that.
What you are looking for is a restart of the whole stream which should be achievable with the recoverWithRetries
combinator (docs). You can feed the same source again (Source(1 to 5)
) to the combinator to have it replay those elements.