tapir
tapir copied to clipboard
Cannot cancel a stream
Tapir version: 1.2.2
Describe the bug
When using a bodyStream endpoint, a download properly start when calling the endpoints, but if I cancel the download, the stream continue in background (in my case calling fetching data in DB).
Not sure how to fix this, do we already have a way to get notified if an http request get aborted? we could plug some kind of a callback to cancel the stream in such case.
Can you provide more details - which intererpreter, what kind of streams? What do you mean by "cancel the download"?
Sure
- VertxFutureServerInterpreter
- Using the brand new
VertxStreamsintroduce here
What I mean by cancelling the download is when I call my GET endpoint that fetch/stream some data from the database, if I call that endpoint from a browser, it start a download like any stuff you would download (usually on the top right corner of your browser) and I just click on the cross to stop the download. Or if I wget my endpoint and in the middle of the download I ctrl-c.
My current work on this is here if you are interested
Hello, as a small starting point, In Pipe if we add a:
writeStream.exceptionHandler
When ctrl-c the request we get a : io.vertx.core.http.HttpClosedException: Connection was closed
Not sure yet how we could bring this info up to the serverLogic
also wanted to know why Pipe is re-defined here? why not using vertx Pipe directly?
Edit: Doing
--- a/server/vertx-server/src/main/scala/sttp/tapir/server/vertx/encoders/VertxToResponseBody.scala
+++ b/server/vertx-server/src/main/scala/sttp/tapir/server/vertx/encoders/VertxToResponseBody.scala
@@ -45,7 +45,7 @@ class VertxToResponseBody[F[_], S <: Streams[S]](serverOptions: VertxServerOptio
charset: Option[Charset]
): RoutingContext => Future[Void] = { rc =>
Future
- .succeededFuture(Pipe(readStreamCompatible.asReadStream(v.asInstanceOf[readStreamCompatible.streams.BinaryStream]), rc.response))
+ .succeededFuture(readStreamCompatible.asReadStream(v.asInstanceOf[readStreamCompatible.streams.BinaryStream]).pipeTo(rc.response))
.mapEmpty()
}
seems to work fine, it even seems that ctrl-c the request actually stop reading my DB :rocket: I still need to check if all resources are well freed to avoid a leak somewhere.
Edit: I don't think it nicely clean everything, I did some experiment to close the pipe, but it just set everything to null. On my app side using akka-streams, it stops pulling data from db, but I'm not sure my akka-streams is properly cleaned or will be garbage collected. I'm currently a bit clueless, but I'll continue the digging.
Edit: This issue seems to say it's all fine, but I guess it's because it's all stay in the vert.x world