I'm trying to use Akka HTTP for POSTing to a webserver. If a POST fails I would like it to stop and not send more POSTs as they are not idempotent.
The code below creates POSTs and sends them to a test web server. It throws an exception on the first response. The code should be runnable in which case you'll see it prints:
i = 0
got response
i = 1
stopping
Exception in thread "main" java.lang.Exception
i = 2
i = 3
i = 4
i = 5
So the 'stopping' happens after the next request has been put together (i = 1
), then the code just continues.
Does anyone know how to stop the flow once there's an error and to not send any further POSTs?
(Scala 2.11.8, Akka 2.4.4)
object FlowTest {
def main(args: Array[String]) {
val stop: Supervision.Decider = {
case _ =>
println("stopping")
Supervision.Stop
}
implicit val system = ActorSystem()
import system.dispatcher
implicit val mat = ActorMaterializer()
val connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]] =
Http().outgoingConnection(host = "posttestserver.com", port = 80)
val future: Future[Done] = Source(0 to 10).map {
i =>
val uri = s"/post.php?dir=so_akka&i=$i"
println(s"i = $i")
HttpRequest(method = HttpMethods.POST, uri = uri, entity = s"data $i")
}.via(connectionFlow).mapAsync(1) {
resp =>
Unmarshal(resp.entity).to[String]
.map { str =>
println(str)
throw new Exception("") // Always fail
str
}
}.withAttributes(ActorAttributes.supervisionStrategy(stop)).runForeach(println)
Await.result(future, Duration.Inf)
}
}