Needs work
Project:
Drupal core
Version:
main
Component:
big_pipe.module
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
30 May 2022 at 12:43 UTC
Updated:
27 Apr 2024 at 17:32 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
wim leershttps://github.com/symfony/symfony/issues/46449 was closed ~30 mins ago: the upstream change that caused this regression was reverted.
Comment #3
wim leersBut @stof makes an interesting point at https://github.com/symfony/symfony/issues/46449#issuecomment-1136082446:
That seems reasonable too.
\Symfony\Component\HttpFoundation\StreamedResponse::setContent()does something similar.This patch does that.
Comment #4
wim leersAnd
adds to that.
I was going to respond that unfortunately we can't, because
class BigPipeResponse extends HtmlResponseandclass HtmlResponse extends Response implements CacheableResponseInterface, AttachmentsInterface.But …Nope, we can't, because we have lots of code doingHtmlResponsebarely does anything. So we can absolutely change this.$response instanceof HtmlResponsechecks … 😬Comment #6
catch@Wim Leers I started looking at the same thing after Stof's comment, but the problem is much less
HtmlResponsethan\Drupal\big_pipe\Render\BigPipe::sendChunk()calls BigPipeResponse::getContent(), which accesses $this->content.And the comment in BigPipeResponse explaining why it can't use StreamedResponse is explicitly because it wants to make $content available to middlewares, instead of putting it behind a callback.
So to me this part of things seemed 100% by design from our end.
The questions for me are:
1. Can we actually use Transfer-Encoding: chunked? We could probably shim the encoding into BigPipe::sendChunk() (also see comment on the original issue) to find out.
2. Is there definitely a reason we can't put $content behind a callback and use streamed response, or otherwise not use that property.
Comment #7
andypostI bet we can touch all this places
Comment #8
wim leersI suppose we should do this before Drupal 10?
Comment #9
andypostI think as it's task it doable in 9.5 too
Comment #11
bradjones1This is important also because any post-response processing (e.g., destructable services) keeps the client "spinner" spinning when the server uses mod_php, even though all the content has been sent. See #3295790-69: Post-response task running (destructable services) are actually blocking; add test coverage and warn for common misconfiguration.
Comment #13
catchRetitling to make it clearer what this is about.
Comment #14
wim leersIdea: if Symfony actually added support for HTTP trailers, then we could change BigPipe to rely on that instead — we wouldn't have to mess with
Response::$contentanymore!Still zero interest in this upstream — maybe you and I could collaborate to figure out how to bring that to Symfony?
EDIT: and that would in principle also allow us to bring https://www.drupal.org/project/big_pipe_sessionless to Drupal core — see the description on that page which also mentions HTTP trailers 🤓
Comment #15
catchHuh interesting, my main interest here in using fully chunked encoding -
so that we can send content length in a way the browser understands. The only drawback is that http2 works against this a bit so it might be already outdated to some extent.
Does trailers help with this or is that mainly for the cache tags bit?
Comment #16
wim leersQuoting MDN:
IOW: it still requires chunked/streamed responses … but it just would fit better with Symfony's desire/intent to disallow manipulating
Response::$content.That's it.
No HTTP-level reason. Only a Symfony-level reason.
Comment #17
catchAhh gotcha, we might need both things then.
Comment #18
longwaveFound this after looking into BigPipe behind Amazon CloudFront, where I don't appear to be seeing the content streamed correctly - instead the response is delivered all in one go.
CloudFront docs say:
BigPipe.php says
but it appears this is not actually true?
Comment #19
mfbAs far as I've seen, Big Pipe does send chunked? All you have to do is print something and then call flush(); and the Transfer-Encoding: chunked header should be added automatically. HTTP/2 or HTTP/3 don't support it though, so you might not literally see a chunked transfer, depending on the stack.
Comment #20
catchOK yeah so PHP is supposed to send it if you call flush() as long as there's not a content length header (which there isn't for bigpipe), which makes this issue title a bit tautological. Good to figure that out before anything actually got going trying to reimplement the encoding in bigpipe though.
But switching to using trailers would be really nice and maybe more compatible with http/2?
Let's retitle. https://www.fastly.com/blog/supercharging-server-timing-http-trailers suggests some CDN support (although not for this use case at all).
Comment #21
mfbre: compatible with HTTP/2, I'd hope that proxies convert HTTP/1.1 chunked transfer to HTTP/2 (or HTTP/3) data frames and pass them along, without excessive buffering, but not something I've analyzed