-
Notifications
You must be signed in to change notification settings - Fork 47
PURGE requests should be non-blocking & Issues with redirection/302/WP HTTP API #56
Comments
Quick answer... Believe it or not, it's never come up. I test on a local box without Varnish to make sure the non purge things work (like the scanner and the debugger and admin stuff). Then I push it to a dev box with Varnish to test Varnish. But this is a legit thing and it's fascinating to me that it hasn't come up before, so I'm going to spend some serious time reading this a couple more times and thinking about what to do with it. My gut likes the idea of a This needs serious thinking. I like the problem and the possible solutions you've found, Jer! |
One thing worth noting: |
Awesome thanks @Ipstenu ! So glad it wasn't just a confusing mess 😅 I think the logging stuff would be a big help to a lot of people, and if nothing else would be good to have for yourself it sounds like. Overall I think that yeah, a lot of people aren't managing their flushes carefully, but really most people should be 🤷🏻♀️ @danielbachhuber Yes, it seems on my local MAMP setup, I'm still in the process of testing it on our live server ([Ubuntu]Nginx->Varnish->Nginx) |
@danielbachhuber I guess even if @jerclarke any results from testing on the linux live server? Have you ever measure doing a |
This was something Barry told me when I attempted to implement usage analytics for WP-CLI wp-cli/wp-cli#3886 I don't know the underlying implementation details off the top of my head. If I were to look into it, I'd start with WordPress/Requests#53 and understanding how cURL and fsockopen implement
It would be nice to have documented, I agree. We'd need to make sure the documentation is actually correct though. |
@danielbachhuber Thanks, I see. Via a Stackoverflow answer, I've came across Guzzle which is supposed to support async http requests aka Futures / Promises according to its FAQ. So I guess this is something that might be worth looking into instead of the EDIT: Well, seems like it's not that simple :-/ after reading: |
FWIW, I added So despite some discussions in #5 (comment) and #66 it looks like it's definitely not easy to solve. Also even if it was I'd like to mention (as nobody has yet) that many hosters have restrictive settings for the number of parallel php processes aka |
This was hell to debug. I discovered it because on my local system, all the
PURGE
calls were going through as actualGET
pageloads, and my macbook was getting overwhelmed loading dozens of pages all at once each time I saved a published post (took over a minute).TL;DR: If the current web server redirects
PURGE
requests as302
then they becomeGET
and load the actual URLs on the site, which makes saving a post extremely slow.TL;DR2: The HTTP API allows requests to be non-blocking and thus not hold up the pageload, why not use
'blocking' => 0
this for this plugin?It was slow because all the
PURGE
s were being done asGET
This part is mostly for information purposes, in case someone else stumbles onto a similar problem, but it also explains my situation and why I think the
'blocking' => 0
solution described below is important.PURGE
requests don't "work" like they should, but we want them to fail silently.PURGE
requests for the dozen relevant URLs each time.GET
, which loads the actual URLs and overwhelms my laptop as a little mini-DOS, making post saving take 1min+It has taken me literally years to figure out that this is what's happening, which is embarassing but related to how deep the problem lies. I had to dig into the logs and add logging deep inside the HTTP API methods to figure it out. The user experience was just that saving was excruciatingly slow on my local site.
After investigation the following became clear:
PURGE
request was being redirected from http->https, and the redirected URL was being fetched asGET
instead ofPURGE
302
, and WP has an explicit (underdocumented) internal filter on the HTTP API that converts ANY302
redirect toGET
regardless of it's starting method. You can read about how this happens on a StackExchange post I created about what's going on: Why does WP HTTP API switch the method (POST/PURGE) to GET when redirecting (302)?Important notes:
302
coming up.301
errors in this same situation. So evenPURGE
requests could redirect successfully.SO: In terms of this HTTP API confusion with redirection anyone with similar problems has a couple of options:
WP_Http->browser_redirect_compatibility()
Bad solution: In
purge_url
, pass'redirection' = 0
towp_remote_request()
This solved my problem with local dev because it means that when my Apache in MAMP gets the purge request and redirects it to HTTPS, it just silently stops.
The problem with this is that if the redirection is a 301, it DOES work! We discovered that our actual live server was relying on this for proper functioning. To me, this implies that this plugin shouldn't disable redirection, because there may be many users relying on the effectiveness of redirected
PURGE
calls, even if in the grander scheme they aren't reliable (and really, everyone should work to make sure their purges are happening without redirection).That said, I wanted to point this out because for some cases it could be a good workaround, and it seemed like a good option to me at first.
Better solution? Use
'blocking' => 0
insteadBy default all WP HTTP API requests are "blocking" and the whole system waits for the resulting
$response
object to be generated and returned. Obviously sometimes this is vital, but in the case of thesePURGE
requests I think the'blocking' => 0
mode would be a really good fit:PURGE
requests to process. It's bad UX for it to be slow, could cause race conditions and if thePURGE
requests don't go well there still won't be any information about it for the user.$response
object at the end ofpurge_url()
, it runs theafter_purge_url
filter but that filter isn't called inside the plugin itself.Have you considered
'blocking' => 0
before? Maybe there's a reason not to use it that I haven't thought of?The main reason I can see is to preserve the current functioning of the filter:
If the non-blocking mode was used, there wouldn't be a
$response
object to include in that filter (or, if left as-is, it would always be a blank default response object).That said, it strikes me that the
$response
object, though useful here, is something we can probably live without as long as the documentation makes it clear that the$response
is always empty because we (logically) use the non-blocking mode for the request.We can still get the response with the
http_api_debug
action inWP_Http->request()
So IDK if this is something you'd want to build into the plugin, but IMHO if making it easy to debug the purging is a priority, and otherwise
'blocking' => 0
makes sense to you, then you can easily document how to debug these purges and/or add it as a plugin feature using the action above:error_log()
duringhttp_api_debug
any time themethod
in$r
(request arguments) isPURGE
This would work just as well as the existing hook, and now that I think of it, you could keep
after_purge_url
intact if you wanted, by creating your own hook onhttp_api_debug
and setting up the variables so thatafter_purge_url
is backwards-compatible.So after all that, the question is: Why not use
'blocking' => 0
as the default mode for the plugin?On my end, despite all this digging, it seems it's still pretty slow on local, even if I set it to
'blocking' => 0
, because MAMP still loads every page and it takes 18 seconds reliably before I get back to the refreshed post editor. If I want to keep this plugin active on my dev environment I think i'll need to set up something that quickly and silently returns 200 forPURGE
requests to mimic Varnish.The text was updated successfully, but these errors were encountered: