woocommerce / action-scheduler

A scalable, traceable job queue for background processing large queues of tasks in WordPress. Specifically designed for distribution in WordPress plugins (and themes) - no server access required.
https://actionscheduler.org
GNU General Public License v3.0
636 stars 116 forks source link

Async Request 1 second timeout #1076

Closed andrewklimek closed 2 months ago

andrewklimek commented 2 months ago

If I understand correctly, an async request to run the queue is fired on every admin page, if it's been 60 seconds since the last run. I'm seeing 1 second timeouts instead of the near instant you would assume from seeing 'timeout' => 0.01, 'blocking' => false

I believe this is because of rounding up to 1 second here. I'm seeing that blocking does anything to help, but i'm not a curl expert by any means.

My test was simple: Replace woocommerce/includes/libraries/wp-async-request.php L85

return wp_remote_post( esc_url_raw( $url ), $args );

with

$timer = microtime(1);
$ret = wp_remote_post( esc_url_raw( $url ), $args );
error_log( "WP_Async_Request took ". (microtime(1) - $timer) );
return $ret;

Then I press update on any product, wait around for a minute, load another admin page, and check the error log. I'm consistently getting just over 1 second.

I have some ideas to fix it, but first I should make sure my test or environment isn't bad somehow.

System Status Report ``` ### WordPress Environment ### WordPress address (URL): [Redacted] Site address (URL): [Redacted] WC Version: 9.1.2 Legacy REST API Package Version: The Legacy REST API plugin is not installed on this site. Action Scheduler Version: ✔ 3.7.4 Log Directory Writable: ✔ WP Version: 6.6.1 WP Multisite: – WP Memory Limit: 512 MB WP Debug Mode: ✔ WP Cron: – Language: en_US External object cache: – ### Server Environment ### Server Info: LiteSpeed PHP Version: 8.0.30 PHP Post Max Size: 2 GB PHP Time Limit: 300 PHP Max Input Vars: 1000 cURL Version: 7.61.1 OpenSSL/1.1.1k SUHOSIN Installed: – MySQL Version: 11.3.2-MariaDB Max Upload Size: 2 GB Default Timezone is UTC: ✔ fsockopen/cURL: ✔ SoapClient: ✔ DOMDocument: ✔ GZip: ✔ Multibyte String: ✔ Remote Post: ✔ Remote Get: ✔ ### Database ### [REDACTED] ### Post Type Counts ### attachment: 1250 oembed_cache: 1 page: 7 post: 2 product: 441 product_variation: 2084 revision: 129 shop_order_placehold: 2287 wpcf7_contact_form: 1 ### Security ### Secure connection (HTTPS): ✔ Hide errors from visitors: ✔ ### Active Plugins (15) ### 8Merch Platform: by Andrew J Klimek – Contact Form 7: by Takayuki Miyoshi – 5.8.7 WPBakery Page Builder: by Michael M - WPBakery.com – 6.8.0 Kirki Customizer Framework: by Themeum – 5.0.0 Meta Box: by MetaBox.io – 5.9.3 Sober Addons: by UIX Themes – 1.6.3 Soo Product Filter: by UIX Themes – 1.0.8 Woo to Woo Product Push: by Andrew J Klimek – 2023-10-05 WooCommerce Table Rate Shipping: by WooCommerce – 3.1.6 (update to version 3.3.0 is available) WooCommerce: by Automattic – 9.1.2 WP Mail SMTP: by WP Mail SMTP – 3.11.1 LightStart - Maintenance Mode, Coming Soon and Landing Page Builder: by Themeisle – 2.6.9 WP Rollback: by WP Rollback – 2.0.6 WPForms Lite: by WPForms – 1.8.6.4 ### Inactive Plugins (1) ### Akismet Anti-spam: Spam Protection: by Automattic - Anti-spam Team – 5.3.1 ### Settings ### API Enabled: – Force SSL: – Currency: EUR (€) Currency Position: left_space Thousand Separator: , Decimal Separator: . Number of Decimals: 2 Taxonomies: Product Types: external (external) grouped (grouped) simple (simple) variable (variable) Taxonomies: Product Visibility: exclude-from-catalog (exclude-from-catalog) exclude-from-search (exclude-from-search) featured (featured) outofstock (outofstock) rated-1 (rated-1) rated-2 (rated-2) rated-3 (rated-3) rated-4 (rated-4) rated-5 (rated-5) Connected to WooCommerce.com: – Enforce Approved Product Download Directories: – HPOS feature enabled: ✔ Order datastore: Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore HPOS data sync enabled: – ### Logging ### Enabled: ✔ Handler: Automattic\WooCommerce\Internal\Admin\Logging\LogHandlerFileV2 Retention period: 30 days Level threshold: – Log directory size: 439 B ### WC Pages ### Shop base: #8 - / Cart: #9 - /cart/ - Contains the [woocommerce_cart] shortcode Checkout: #10 - /checkout/ - Contains the [woocommerce_checkout] shortcode My account: #11 - /my-account/ Terms and conditions: ❌ Page not set ### Theme ### Name: Sober Version: 2.3.1 Author URL: http://uix.store Child Theme: ❌ – If you are modifying WooCommerce on a parent theme that you did not build personally we recommend using a child theme. See: How to create a child theme WooCommerce Support: ✔ ### Templates ### Overrides: sober/woocommerce/cart/cart-shipping.php version 3.6.0 is out of date. The core version is 8.8.0 sober/woocommerce/cart/cart.php version 3.8.0 is out of date. The core version is 7.9.0 sober/woocommerce/cart/mini-cart.php version 3.7.0 is out of date. The core version is 7.9.0 sober/woocommerce/checkout/form-checkout.php sober/woocommerce/checkout/form-coupon.php version 3.4.4 is out of date. The core version is 7.0.1 sober/woocommerce/checkout/form-login.php sober/woocommerce/checkout/review-order.php version 3.8.0 is out of date. The core version is 5.2.0 sober/woocommerce/global/form-login.php version 3.6.0 is out of date. The core version is 7.0.1 sober/woocommerce/global/quantity-input.php version 4.0.0 is out of date. The core version is 7.8.0 sober/woocommerce/global/wrapper-end.php sober/woocommerce/global/wrapper-start.php sober/woocommerce/loop/add-to-cart.php version 3.3.0 is out of date. The core version is 9.0.0 sober/woocommerce/loop/price.php sober/woocommerce/loop/result-count.php sober/woocommerce/myaccount/dashboard.php version 2.6.0 is out of date. The core version is 4.4.0 sober/woocommerce/myaccount/form-edit-account.php version 3.5.0 is out of date. The core version is 8.7.0 sober/woocommerce/myaccount/form-login.php version 4.1.0 is out of date. The core version is 7.0.1 sober/woocommerce/myaccount/my-address.php version 2.6.0 is out of date. The core version is 8.7.0 sober/woocommerce/notices/error.php version 3.9.0 is out of date. The core version is 8.6.0 sober/woocommerce/notices/success.php version 3.9.0 is out of date. The core version is 8.6.0 sober/woocommerce/order/form-tracking.php version 3.6.0 is out of date. The core version is 7.0.1 sober/woocommerce/single-product/add-to-cart/external.php version 3.4.0 is out of date. The core version is 7.0.1 sober/woocommerce/single-product/add-to-cart/grouped.php version 4.0.0 is out of date. The core version is 7.0.1 sober/woocommerce/single-product/add-to-cart/simple.php version 3.4.0 is out of date. The core version is 7.0.1 sober/woocommerce/single-product/add-to-cart/variable.php version 3.5.5 is out of date. The core version is 6.1.0 sober/woocommerce/single-product/add-to-cart/variation-add-to-cart-button.php version 3.4.0 is out of date. The core version is 7.0.1 sober/woocommerce/single-product/product-image.php version 3.5.1 is out of date. The core version is 9.0.0 sober/woocommerce/single-product/product-thumbnails.php sober/woocommerce/single-product/related.php sober/woocommerce/single-product/review-meta.php sober/woocommerce/single-product/tabs/additional-information.php sober/woocommerce/single-product/tabs/tabs.php sober/woocommerce/single-product/up-sells.php sober/woocommerce/single-product-reviews.php version 3.6.0 is out of date. The core version is 4.3.0 Outdated Templates: ❌ Learn how to update ### Admin ### Enabled Features: activity-panels analytics product-block-editor coupons core-profiler customize-store customer-effort-score-tracks import-products-task experimental-fashion-sample-products shipping-smart-defaults shipping-setting-tour homescreen marketing mobile-app-banner navigation onboarding onboarding-tasks product-custom-fields remote-inbox-notifications remote-free-extensions payment-gateway-suggestions shipping-label-banner subscriptions store-alerts transient-notices woo-mobile-welcome wc-pay-promotion wc-pay-welcome-page launch-your-store Disabled Features: experimental-blocks minified-js pattern-toolkit-full-composability product-pre-publish-modal printful settings async-product-editor-category-field product-editor-template-system Daily Cron: ✔ Next scheduled: 2024-07-25 15:19:47 +00:00 Options: ✔ Notes: 194 Onboarding: completed ### Action Scheduler ### Complete: 936 Oldest: 2024-06-24 16:04:28 +0000 Newest: 2024-07-25 15:21:47 +0000 Failed: 21 Oldest: 2023-02-20 10:00:43 +0000 Newest: 2023-12-31 00:06:39 +0000 Pending: 7 Oldest: 2024-07-25 16:56:24 +0000 Newest: 2024-07-31 20:04:46 +0000 ### Status report information ### Generated at: 2024-07-25 15:29:15 +00:00 ```
barryhughes commented 2 months ago

@andrewklimek,

Apologies as, when you raised this originally, I noted I couldn't replicate—but my test was flawed (specifically, I was testing against a site where the request resolved rapidly, which didn't really allow for the problem to be seen). I think one of the challenges we have here, though, is covered by a note found in WP's Requests class:

 * - `timeout`: How long should we wait for a response?
 *    Note: for cURL, a minimum of 1 second applies, as DNS resolution
 *    operates at second-resolution only.

cURL is not the only backend that is available, but I'd be a little reticent to try and override this choice. That said, definitely interested in your ideas here.

andrewklimek commented 2 months ago

@barryhughes

It seems that cURL does let you use less than 1 second timeout if you set CURLOPT_NOSIGNAL to true. I tested this but it's not really a great solution to hardcode such a short timeout as .01 ... sometimes the call would fail. I found .03 to be more reliable but obviously not a great idea.

It seems like the better solution is to have the script hang up the connection as soon as possible, as wp-cron.php does with fastcgi_finish_request() and litespeed_finish_request().

I added these to the wpajax handler and it cut down the time nicely, but wp-cron.php is still faster. Obviously it still takes time for admin-ajax.php to load everything it does before it finally fires the wpajax hook... whereas wp-cron.php just hangs up right away.

So the fastest options I can think of are:

  1. make a very similar file to wp-cron.php and send the async calls to that custom file... I like this option best, the only trick is getting the path to wp-load.php before ABSPATH is defined.

  2. hook into wp_get_ready_cron_jobs() and run there (would need to switch from POST to GET to get that far).

barryhughes commented 2 months ago

Thanks ... I think we also need determine if a fix is best applied here, by us, or upstream (WP Background Processing library) 🤔

barryhughes commented 2 months ago

Let me know if you feel differently, but since this is inside a dependency I think it does indeed make the most sense to report over there (then, numerous projects besides this one can take advantage of any improvements).