Opened 3 years ago
Closed 17 months ago
#54166 closed defect (bug) (fixed)
Updating errors due to PHP timeouts
Reported by: | aristath | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | 6.2 | Priority: | normal |
Severity: | normal | Version: | 6.0 |
Component: | Upgrade/Install | Keywords: | has-patch |
Focuses: | Cc: |
Description
Initially reported in https://core.trac.wordpress.org/ticket/51857#comment:128
After [51815] there is an error when updating large plugins such as Gutenberg or WooCommerce.
After debugging the issue, it seems to be due to a PHP timeout and depends on the server's configuration (which is why the failure only occurs for large plugins).
The way we delete a directory in PHP is by going through all files in that directory and deleting them one by one (as far as I know this is the only way). As a result, deleting or restoring a backup of a large plugin takes more time than expected.
Change History (65)
This ticket was mentioned in PR #1696 on WordPress/wordpress-develop by aristath.
3 years ago
#1
- Keywords has-patch added; needs-patch removed
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
3 years ago
peterwilsoncc commented on PR #1696:
3 years ago
#4
I'm still hitting fatal errors occasionally during the update process.
In the screenshot it happened with Gutenberg, updating via "Dashboard > Updates > View details about... > Click install".
During testing last week it was happening consistently but now it's only happening intermittently, so this PR is an improvement.
#5
@
3 years ago
As noted on the pull request, I am still seeing fatal errors when testing this locally.
Both gutenberg
and wpforms-lite
intermittently end up with either some or all of their sub-directories empty.
There are backward compatibility implications but I am wondering if it's possible to switch to a series of AJAX requests for each step:
- Create the backup of the previous install
- Download the update from w.org
- Unzip the download
- Activate the plugin
- Restore if needs be
As fetch returns a promise, it's offers quite a lot of control to ensure the process doesn't get ahead of itself.
- No requirements
- No requirements
- Requires 1, 2 be complete
- Requires 1, 2, 3, be complete
- Requires 1 be complete, 4 to fail
#6
@
3 years ago
Please note: @aristath, @pbiron and I have some further notes relating to this issue on the original ticket from comment #137 onwards.
This ticket was mentioned in PR #1727 on WordPress/wordpress-develop by afragen.
3 years ago
#7
Add a move_dir()
function for use in WP_Upgrader instead of copy_dir()
. There seem to be timeout issues in slower systems like Vagrant or the WP Docker test env with installation or update of large plugins like WooCommerce, Yoast SEO, or MailPoet.
This new function attempts a rename()
and falls back to the previous copy_dir()
.
Trac ticket: https://core.trac.wordpress.org/ticket/54166
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core by afragen. View the logs.
3 years ago
#16
follow-up:
↓ 20
@
3 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening this as I think r51899 will need to be reverted:
rename()
should not be inmove_dir()
-- different file systems use different functions, egftp_rename()
- If the destination exists, it is always overwritten. This seems problematic and there should really be an
$overwrite
parameter per the other functions - In
_wp_handle_upload()
it's noted thatrename()
fails on streams, so that may be problematic & streams handled differently ('may' is the key word, with the other issues I haven't researched this)
When trying to debug this issue with @afragen on Friday, I was testing with the pull request applied and still having the problem so I am not sure it fixes the reported issue completely either.
Reading the code and doing some logging earlier today, I think something that runs asynchronously isn't been accounted for which is leading to the error.
Installing/updating akismet (a very small plugin) was showing different contents within the working directory at several points within the procedure.
#17
@
3 years ago
Just for reference, if rename()
fails the function reverts to copy_dir()
, which was there previously. File systems not having a rename()
command should continue to function as they did previously.
The previous flow always emptied the specific plugin folder in wp-content/plugins/
that's why a failed update would leave an empty folder. The $clear_destination
parameter is always true when updating. https://github.com/WordPress/wordpress-develop/blob/6367c01844e34dd372b999beb0e370f52d8c42d5/src/wp-admin/includes/class-plugin-upgrader.php#L222-L239
I don't believe streams are ever utilized in the plugin update process.
While Peter and I haven't yet been able to figure out the issue on his system using Vagrant and Chassis, I don't believe that reverting r51899 will fix it.
#18
@
3 years ago
In a discussion with @aristath today, it was pointed out that PR 1696 is also ready for commit, so let's try that as well.
#20
in reply to:
↑ 16
;
follow-up:
↓ 24
@
3 years ago
Replying to peterwilsoncc:
Reopening this as I think r51899 will need to be reverted
Yeah, now that I think of it, I also have some concerns with the function:
- It does not use the
WP_Filesystem_*
methods, so therename()
call will only work if direct PHP file access is available. - The fallback to
copy_dir()
causes inconsistent behavior:- If the
rename()
call worked, the source directory is successfully renamed and does not need any further actions. - If the
rename()
call failed, the source directory is left behind and has to be cleaned separately.
- If the
I wonder [51899] is still needed after [51902], or after getting to the bottom of the issue from comment:16.
SergeyBiryukov commented on PR #1696:
3 years ago
#21
Thanks for the PR! Merged in https://core.trac.wordpress.org/changeset/51902.
This ticket was mentioned in PR #1747 on WordPress/wordpress-develop by afragen.
3 years ago
#22
Update for r51899 to address issues, https://core.trac.wordpress.org/ticket/54166#comment:20
- Add check for direct PHP flle access and only use
rename()
if true. - More consistent behavior for fallback to
copy_dir()
Trac ticket: https://core.trac.wordpress.org/ticket/54166
3 years ago
#23
Use move_dir()
for moving and restoring to backup directory as $wp_filesystem->move()
fallback is a file copy and that will cause problems.
#24
in reply to:
↑ 20
;
follow-up:
↓ 25
@
3 years ago
Replying to SergeyBiryukov:
Replying to peterwilsoncc:
Reopening this as I think r51899 will need to be reverted
Yeah, now that I think of it, I also have some concerns with the function:
- It does not use the
WP_Filesystem_*
methods, so therename()
call will only work if direct PHP file access is available.- The fallback to
copy_dir()
causes inconsistent behavior:
- If the
rename()
call worked, the source directory is successfully renamed and does not need any further actions.- If the
rename()
call failed, the source directory is left behind and has to be cleaned separately.I wonder [51899] is still needed after [51902], or after getting to the bottom of the issue from comment:16.
I think I have addressed the above concerns in a new PR#1747
I believe move_dir()
is still needed it does address a potential timeout issue and does create a directory move that doesn't fallback to a PHP copy()
that may fail when attempting to copy directories.
#25
in reply to:
↑ 24
@
3 years ago
Replying to afragen:
Yeah, now that I think of it, I also have some concerns with the function:
- It does not use the
WP_Filesystem_*
methods, so therename()
call will only work if direct PHP file access is available.- The fallback to
copy_dir()
causes inconsistent behavior:
- If the
rename()
call worked, the source directory is successfully renamed and does not need any further actions.- If the
rename()
call failed, the source directory is left behind and has to be cleaned separately.I wonder [51899] is still needed after [51902], or after getting to the bottom of the issue from comment:16.
I think I have addressed the above concerns in a new PR#1747
Thanks for the PR! I think it addresses the first concern, but not the second. After the fallback to copy_dir()
, I think the source directory should be removed. Currently, in that scenario, move_dir()
is just an alias for copy_dir()
, as it performs the copying part, but does not clean up the source directory like the move_dir()
name suggests, unless I'm missing something.
Addressing that would make the clear_working
parameter of WP_Upgrader::install_package()
a bit redundant, as the working directory would always be cleared regardless of its value. However, it is already redundant in case the rename()
call worked. If move_dir()
stays, the clear_working
parameter would probably have to be deprecated.
3 years ago
#26
Updated to clear the working directory so there is internal parity within the function with the results of a successful rename()
.
As @SergeyBiryukov points out, this may deprecate the clear_working
option.
This ticket was mentioned in Slack in #core by sergey. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-auto-updates by peterwilsoncc. View the logs.
3 years ago
#30
@
3 years ago
Please see my full comment on the original ticket.
I've come to the conclusion that the following commits need to be reverted and the reliability improvements added in a subsequent release:
Repeating the tl;dr here but let's discuss pros and cons on the other ticket.
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-test by boniu91. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-auto-updates by hellofromtonya. View the logs.
3 years ago
#38
@
3 years ago
Thanks everyone! Keeping this open for now to see if the clear_working
parameter is still relevant or should be deprecated, as per comment:25.
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
3 years ago
SergeyBiryukov commented on PR #1747:
3 years ago
#40
Thanks for the PR! Merged in https://core.trac.wordpress.org/changeset/52289.
#41
@
3 years ago
- Milestone changed from 5.9 to 6.0
The Upgrade/Install team working on #51857 and this ticket decided to revert all of the changesets and move the work to early 6.0.
Why? An unidentified problem exists on virtualized systems using Vagrant and/or VirtualBox (with tools such as VVV, chassis, and potential others).
Once the 5.9 is branched and 6.0-alpha in trunk is open for business, the changesets will be recommitted to restore the work for continued investigation, refinement, and extensive testing.
This ticket was mentioned in Slack in #core-auto-updates by peterwilsoncc. View the logs.
3 years ago
#44
@
3 years ago
I strongly suspect this is related to this issue on the composer github:
https://github.com/composer/composer/issues/9627
Specifically:
public static function workaroundFilesystemIssues() { if (self::isVirtualBoxGuest()) { usleep(200000); } }
You need to sleep for a small amount of time so that filesystem caches are flushed.
When dealing with shared folders and mounts there are many approaches to tackle the performance vs latency tradeoff. For example some Docker implementations sacrifice CPU performance for filesystem immediacy. VirtualBox uses small caches with ultra short expiration dates. By calling usleep composer worked around this issue. Composer calls that function after every batch of filesystem calls to ensure that the FS can catch up before the next batch happens.
Other things to note:
- this can be tested by performing the tests on a WordPress install that is not located in a shared/mounted folder
- other filesystems that have latency issues or micro-caches should exhibit intermittent forms of this behaviour
- On Windows+Hyper-V VirtualBox will transparently use Hyper-V behind the scenes due to nested virtualisation restrictions. People trying to reproduce this on Windows may not get the same results because of this.
#45
@
3 years ago
I also suspect this command may influence the results of the tests:
VBoxManage storagectl "VM name" --name <controllername> --hostiocache off
Based on https://www.virtualbox.org/manual/ch05.html#iocaching
I would note that this is the main reason we do not mount the MySQL/MariaDB data folders as shared folders by default. The database server can become unstable when shared DB folders are turned on depending on the workload and the nature of the underlying OS and Hardware.
#46
@
2 years ago
- Keywords dev-feedback added
- Version changed from 5.9 to trunk
Per the discussion in the bug scrub, I'm adding the dev-feedback
keyword to get as much input on this as possible.
This ticket is touched by PR 2225. As such, this would greatly benefit from additional testing, particularly on different filesystems. See this comment for the current state of things.
Changing the version to trunk
as [51815] was reverted in [52351] prior to 5.9's release.
This ticket was mentioned in Slack in #core by chaion07. View the logs.
2 years ago
This ticket was mentioned in Slack in #core by chaion07. View the logs.
2 years ago
This ticket was mentioned in Slack in #core-auto-updates by afragen. View the logs.
2 years ago
This ticket was mentioned in Slack in #core by costdev. View the logs.
2 years ago
#52
@
2 years ago
As a reminder, per comment 46, this ticket is touched by PR 2225 for the Rollback feature.
This ticket is being kept open to ensure that the fix is verified once the Rollback ticket (#51857) lands in Core.
Fixes PHP timeouts by moving the backup deletion & restore to the
shutdown
action.Processes running on
shutdown
are immune to PHP timeouts, so moving them there allows them to run _after_ the main process, without affecting the update.Trac ticket: https://core.trac.wordpress.org/ticket/54166#ticket