laminas / laminas-httphandlerrunner

Execute PSR-15 RequestHandlerInterface instances and emit responses they generate.
https://docs.laminas.dev/laminas-httphandlerrunner/
BSD 3-Clause "New" or "Revised" License
63 stars 20 forks source link

Add flush after header sent #4

Closed mariusbuescher closed 4 years ago

mariusbuescher commented 4 years ago
Q A
Documentation no
Bugfix no
BC Break no
New Feature yes
RFC yes
QA no

Description

This patch makes it possible to send the headers before the content is sent to the client, so they can already be processed and evaluated before the first results show up.

This is especially interesting when having big streamed responses, like a csv report. It also makes it possible to implement one shot server sent events.

There is no change in using the components.

weierophinney commented 4 years ago

Thanks, @amriusbuescher!

willemstuursma commented 4 years ago

Is there some reason this was not added to the \Laminas\HttpHandlerRunner\Emitter\SapiEmitter?

mariusbuescher commented 4 years ago

@willemstuursma excelent question. IMHO the \Laminas\HttpHandlerRunner\Emitter\SapiEmitter should not do some streaming stuff like flushing headers. I expect the SapiEmitter to be blocking, while the SapiStreamEmitter is expected to be non-blocking.

My initial idea was to have an event loop running in the background doing some heavy IO tasks, like a big query to a database and receiving the data in a streamed format. It can then stream the data very quick to the client, so it does not have to wait that long.

Is that enough of explanation or do you have some more questions?

willemstuursma commented 4 years ago

@mariusbuescher They are actually both blocking: the difference is that one outputs the entire response body at once while the other outputs it piece by piece. The latter is useful for, e.g., streaming files.

But I think both could benefit from the flush() call in between. That will send the headers to the client which can then start processing the response. The method of outputting (direct or from a stream) is not relevant for that. Hence that I was surprised.

mariusbuescher commented 4 years ago

@willemstuursma yes, that ist right, both are blocking. But as I see it, the streaming emitter is already made for streaming (so you predict it to stream stuff, even headers), but the simple one, that flushes all at once, I would expect this one to do it all in one flush().