drogon icon indicating copy to clipboard operation
drogon copied to clipboard

Support asynchronous HttpResponse::newStreamResponse

Open tripleslash opened this issue 2 years ago • 3 comments

Currently the handler invoked by HttpResponse::newStreamResponse does not pass in a callback or allow a coroutine task to call the response callback. It directly expects me to write to the response buffer/size in a synchronous/blocking fashion. I want to support asynchronous server-sent event streaming where I deliver push messages via a server-sent text/event-stream endpoint (https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)

https://github.com/drogonframework/drogon/pull/1156#issuecomment-1159808923

Described the issue very well here. We need some mechanism to allow throttling inside streaming callbacks because the data to be streamed might not be available just yet. So we want to return a length of 0 but prevent the chunking callback from closing the connection because more data might be available later.

If I use a condition variable and a mutex to accomplish what I want then the server can deadlock because it steals a worker from the drogon/trantor thread pool. What I am looking for is a way to have HttpResponse::newAsyncStreamResponse that gives the stream handler a completion callback that I can invoke once I have more data available instead of requiring me to directly return that data.

tripleslash avatar May 03 '23 16:05 tripleslash

Do you see a way to support this throttling behavior with minimal invasion? I've looked at the chunking callback and added a special case for when -1 is returned then the connection is not closed and a length of 0 is returned to the trantor stream callback. But this callback is called in sendFileInLoop and i dont quite understand everything it does with it or how sendFileInLoop is even called by the framework. Does it support rescheduling or does it want to send the entire streaming content at once? If it is the latter then i think bigger adjustments inside trantor need to be made?

tripleslash avatar May 04 '23 07:05 tripleslash

I think it's not easy based on the current API of trantor. We should add a new abstraction for this.

an-tao avatar May 05 '23 12:05 an-tao

Is it possible newStreamResponse could use a different trantor send implementation then to support this more easily?

tripleslash avatar Oct 20 '23 06:10 tripleslash