Make WordPress Core

Opened 8 months ago

Last modified 3 months ago

#61903 new defect (bug)

Unable to save draft when tab is open for a long time

Reported by: janvandenberg's profile janvandenberg Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.6.1
Component: General Keywords:
Focuses: Cc:

Description

I've encountered an issue while writing longer articles with many links in WordPress. After a while, the "Save" button becomes unresponsive, as if there's no connection, and I can't save the draft.

When I try to access /wp-admin in another tab, it fails to load, even though other websites work fine. To continue editing, I have to open an incognito window, log into /wp-admin, and close the original draft tab—something seems to be locked.

I'm unsure whether this is a WordPress or web server issue and would appreciate any guidance on how to debug it. I've saved the console log, which might be useful: https://piks.nl/upload/upload/janvandenberg.blog-1724222179856.log

Change History (2)

#1 @TJNowell
3 months ago

Encountered this on a client device, and managed to do some debugging:

  • This only affects chromium based browsers
  • But it can be reproduced using Firefox if max simultaneous connections is set to 1
  • Chromium error logs when the browser is launched in debug mode don't reveal anything
  • No server side errors, HTTP 504's, etc, it appears the requests are handled normally at the server end.

Connections made via fetch and the apiFetch WP package don't appear to close properly after the request is completed. The socket remains open but does not get reused for new connections for some reason.

When the socket pool reaches its maximum all new connections are stuck, be that WP Heartbeat or even dashboard pages in new tabs. This continues until the original tab is closed and a hard refresh occurs, or, the chrome socket pool is flushed, disconnecting all sockets.

I managed to confirm this hypothesis using the net events recorder which confirmed that 6 sockets remained open and unused in the socket page of the net event viewer.

Of note, although WP heartbeat connections failed, they would timeout at 30 seconds whereas connections attempted via apiFetch to the REST API would remain stalled/pending. This lead us down a rabbit hole theorising that WP Heartbeat was using up available sockets, but this was a dead end and incorrect. We also confirmed the 30s was not due to something server side but a hardcoded value in the heartbeat JS.


We managed to work around this by introducing a middleware that added a 30 second timeout via an abort signal to all REST API calls:

import apiFetch from '@wordpress/api-fetch';

/**
 * Add a 30s timeout to all API fetches so that sockets get freed up.
 */
apiFetch.use( ( options, next ) => {
	return next( {
		...options,
		signal: AbortSignal.timeout( 30000 ),
	} );
} );

We weren't expecting this to resolve the issue though, and expected it would make the block editor indicate there was an error rather than getting stuck. Perhaps this changed the handling of the socket in chromiums net stack enough to avoid the issue? I suspect an equivalent bug is being tracked somewhere on the chromium bug tracker.

We also theorise that because the connections are made over HTTP 1.1 that upgrading to HTTP/2 would help here, but we've been unable to verify this as it involves an approval process and multiple departments.

#2 @TJNowell
3 months ago

Of note a colleague was also able to eliminate our codebase as a potential cause by reproducing the issue on a completely different codebase. This looks like a general chromium bug.

Personally I was able to reproduce it by clicking save draft and saving 6 times, on the 7th the button would get stuck on "saving" and all requests to the domain would be stuck regardless of tab or type ( AJAX/fullpage/etc ).

We also eliminated firewall/connection/VPN/rate limiting as while in this stuck state it's possible to launch a separate browser such as safari or firefox and things worked just fine.

Note: See TracTickets for help on using tickets.