#25542 closed enhancement (duplicate)
Function "set_site_transient" is executed twice for plugins - Is it necessary?
Reported by: | johnstonphilip | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | trivial | Version: | 3.6.1 |
Component: | Performance | Keywords: | 2nd-opinion needs-testing dev-feedback |
Focuses: | Cc: |
Description
In the "wp-includes/update.php" file, the "set_site_transient" function is executed twice for 'update_plugins' on lines 195 and 217. This is causing a slowdown that may not need to exist when checking for new updates.
In the "set_site_transient" function (found in the "wp-includes/option.php" file) there is a filter called "pre_set_site_transient_" which is used to hook new plugin updates. Because the "set_site_transient" function is called twice as outlined above, this filter also is called twice which means all of the functions attached to it get called twice as well.
I tested removing the first call to it on line 195 and it doesn't appear to change anything in the multiple tests I have done.
There is a comment above the call on line 195 which I don't understand and reads:
"Update last_checked for current to prevent multiple blocking requests if request hangs".
The problem with having this filter being called twice is that when doing custom API calls for plugin updates, it is checking the API twice for EACH plugin. This ends up increasing the time it takes to check for updates by double. If I have 10 plugins installed, that translates into 20 API checks.
I feel like if there was a way around setting this transient twice, the amount of time it takes to do plugin updates could potentially be cut in half.
I could be wrong so I'm wondering if anyone could test this as well to confirm.
Sidenote: It is also executed twice for:
- "update_core" (line 47 and line 120)
- "update_themes" (line 302 and line 323)
However, I have not yet tested removing the duplicate for these.
Change History (11)
#4
@
11 years ago
Just tested this again in 3.7.1.
Problem and solution appear to be the same. The lines have changed as follows from 3.6.1 to 3.7.1:
Line 47 is now Line 58 (Removed this line and no errors seem to appear)
Line 120 is now Line 149 (Keep this line).
Line 195 is now Line 229 (Removed this line and no errors seem to appear)
Line 217 is now Line 280 (Keep this line).
Line 302 is now Line 369 (Removed this line and no errors seem to appear)
Line 302 is now Line 417 (Keep this line).
I have done multiple tests again on this and can confirm that in my tests, no errors have appeared.
If you would like to test this out for yourself, replace all the code in the wp-includes/update.php file with this code:
http://pastebin.com/ep3w2zUy
In that code I have commented out the duplicate set_site_transient function calls for core, plugins and themes.
#5
@
11 years ago
It might speed up the process, but it would stop the prevention of multiple blocking requests if request hangs, as the comment says. This isn't a change we can make.
You should cache your own API call within your own transient, or just non-persistently cache it, that way you aren't doing the exact same request multiple times on the same page. Maybe in the future we might also introduce better hooks here.
#6
@
11 years ago
Hey @nacin - thanks for responding. I see what you're saying now.
I thought of caching it in my own transient - but there aren't any hooks in the update check process that I can use to do so - at least none that I have found. Is there an action hook I am missing that might be useful here?
Just to play with it, I added an action hook on line 257 of update.php tentatively called "custom_api_calls". Here's a paste bin with it added:
http://pastebin.com/WY7LLeUp
Then in my plugin I just add this function which is hooked to that action to save all my custom plugin data in a transient:
function my_custom_api_calls_action() { $custom_api_plugins = new stdClass(); //My wp_remote_post to my custom api is in a function which hooks to this filter: $custom_api_plugins = apply_filters( 'my_custom_plugins_filter', $custom_api_plugins ); set_site_transient( 'my_custom_plugins', $custom_api_plugins); } add_action( 'custom_api_calls', 'my_custom_api_calls_action' );
And then I feed that back into the "pre_set_site_transient_update_plugins" filter using this function:
function pre_set_site_transient_update_plugins_filter( $_transient_data ) { if( empty( $_transient_data ) ) return $_transient_data; //Get the custom plugins we have added to our custom transient $api_responses = get_site_transient('my_custom_plugins'); //Loop through each custom plugin in the custom transient object foreach ( $api_responses->response as $plugin_name => $api_response ){ //Add each custom plugin to the pre_set_site_transient_update_plugins value $_transient_data->response[$plugin_name] = $api_response; } //Return the new array which includes all custom plugins and WP.org plugins return $_transient_data; } add_filter( 'pre_set_site_transient_update_plugins', 'pre_set_site_transient_update_plugins_filter' );
And it works like a charm :)
Do you think adding an action hook on line 257 is a possibility?
#7
@
11 years ago
What you should probably be doing is, on the first transient set, make your API call, cache it for an hour. On the next transient set, simply re-use the already-cached data and don't make another API call..
#8
@
11 years ago
@dd32 I'm playing with that and it seems to be working. I set the custom transient to expire after 10 seconds. That way I don't have plugins staying in the update list for up to an hour after they have been updated. It isn't the most elegant of solutions but it works.
The only question I'm wondering is if a transient is overkill here. Would a global "counter" variable be a less intensive option? I could increment the counter variable and set the wp_remote_post to only fire if the counter is '2', and then reset it back to 1. Or is that a bad idea?
I appreciate the advice. Thanks guys.
I just want to clarify that I tested removing the first call to it on line 195 and it doesn't appear to have any negative effect. Also, it does speed up the update process by double.