New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transactions, caching, and version transient cleanup issues #20537
Conversation
includes/class-wc-cache-helper.php
Outdated
@@ -136,7 +136,7 @@ public static function get_transient_version( $group, $refresh = false ) { | |||
$transient_value = get_transient( $transient_name ); | |||
|
|||
if ( false === $transient_value || true === $refresh ) { | |||
self::delete_version_transients( $transient_value ); | |||
self::queue_delete_version_transients( $transient_value ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still one failing unit test. It seems to be caused by this change, as reverting this line to instantly delete makes it pass again.
If there is potential for this to cause issues, maybe have the deferred transaction delete only happen if a defined constant is true (e.g. WC_DEFER_TRANSACTION_DELETE
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests run so quick I assume it's because time()
is returning the same value. Thats a bug.
Codecov Report
@@ Coverage Diff @@
## master #20537 +/- ##
=========================================
Coverage ? 28.21%
Complexity ? 13227
=========================================
Files ? 356
Lines ? 49707
Branches ? 0
=========================================
Hits ? 14021
Misses ? 35686
Partials ? 0
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recent changes look good and all tests pass.
This commit reverts commits 2f8a3ea and 17e97c2 that were created to defer transient cleanup (see #20537) and avoid deadlocks on the wp_options table (see #20528 and #17632). The problem is that deferring transient cleanup to a cron job created an issue when creating or importing multiple products at once (see #21100 and woocommerce/wc-smooth-generator#14 (comment)) and has the potential to impact the checkout as well if we start using more versioned transients for orders. This problem is happening because when importing or creating multiple products at once, for each product that is created or imported, WooCommerce core enqueues a few 'delete_version_transients' cron events. Events are enqueued faster than they are executed and after a few hundred products are generated, the size of the cron queue, which is stored in a single wp_options entry, starts to impact WordPress performance in general. To reduce the chance of deadlocks happening again after this change, I already created another PR to optimize the query used to delete transients (#21274) by avoiding an unnecessary filesort, and I'm planning, on a subsequent commit, to improve it further by prefixing the transient name with its version instead of suffixing it as it is currently done. But the ultimate solution for high traffic stores is to use a persistent cache plugin.
This commit reverts commits 2f8a3ea and 17e97c2 that were created to defer transient cleanup (see #20537) and avoid deadlocks on the wp_options table (see #20528 and #17632). The problem is that deferring transient cleanup to a cron job created an issue when creating or importing multiple products at once (see #21100 and woocommerce/wc-smooth-generator#14 (comment)) and has the potential to impact the checkout as well if we start using more versioned transients for orders. This problem is happening because when importing or creating multiple products at once, for each product that is created or imported, WooCommerce core enqueues a few 'delete_version_transients' cron events. Events are enqueued faster than they are executed and after a few hundred products are generated, the size of the cron queue, which is stored in a single wp_options entry, starts to impact WordPress performance in general. To reduce the chance of deadlocks happening again after this change, I already created another PR to optimize the query used to delete transients (#21274) by avoiding an unnecessary filesort, and I'm planning, on a subsequent commit, to improve it further by prefixing the transient name with its version instead of suffixing it as it is currently done. But the ultimate solution for high traffic stores is to use a persistent cache plugin.
3 changes here, all semi-related, which should be rolled out to prevent current conflicts.
This should also help with #17660, however we're not 100% sure as we're unable to replicate the cases in that thread.
This PR reverts some changes made in 1918e2e which has been causing odd issues on stores due to deadlocks, and is potentially guilty of causing double charges on woo.com (cc @kloon).
To Test:
Transactions
Transactions were used so changes could be rolled back, however, it seems this is causing issue if large amounts of data are written due to all the hooks that fire. e.g. in #20528 Not using transactions could lead to partial updates, however, these are not expected and only occur if something (plugin?) causes an error. As such, I'm confident logging will be enough for an admin to resolve.
Disabling transactions seemed to have a positive impact on woo.com, so rolling this out as a fix.
Transient cleanup
Related to the above and raised in #20528. I noticed cleanup runs immediately. We don't need to clean up right away and slow the current process. Deferring the event via cron will work.
Cache ID 0
Not confirmed, but we theorised caching for order ID 0 could be a factor in #17660. This PR simply checks to ensure there is an ID before using caching.
Closes #17660
Closes #20528