Opened 2 years ago
Last modified 2 months ago
#55969 new enhancement
The function set_transient should have the autoload argument
Reported by: | giuse | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.0 |
Component: | Options, Meta APIs | Keywords: | has-patch |
Focuses: | performance | Cc: |
Description
The function set_transient should have an argument to decide if a specific transient should be autoloaded or not so.
At the moment every transient that is set with the function set_transient is autoloaded.
Not all the transients have the need to be autoloaded. For example, many times transients that are used only in the backend don't need the autoload, but they slow down the frontend in some cases.
Change History (11)
#2
@
2 years ago
Temporary values should definitely not be autoloaded
It makes sense, I would totally agree if the sentence was without "definitely". You may have some rare situations where you want the autoload also for this kind of transients. Why don't give me the possibility to choose? Imagine transients that expire after 1-2 months. For 1-2 months I want them autoloaded.
You can't predict all the cases. It's perfect to have as default the autoload that has a sense for most cases, but why don't give the possibility to choose?
If I don't explicitly assign the autoload parameter it would be as it is now, and if I assign it, it means that I need to assign it.
Should permanent transients always be autoloaded? Also in this case, as a default yes, but you should be able to choose. You may need permanent transients that are not autoloaded. For example, permanent transients that run in the backend.
I would assign it as a default as it is now, but give the possibility to change the autoload if needed. The same as you do with normal options.
#3
@
2 years ago
Since this is all done in code, you can create a transient without expiry and manage updates to it yourself.
I'm wondering about the use case of this, though. Why do you need this, specifically?
On the other hand, to prevent autoloading, you can use 100 years (3153600000) for the expiration value.
#4
@
2 years ago
Do you see any downsides in modifying the function with something like this?
<?php function set_transient( $transient, $value, $expiration = 0,$custom_autoload = null ) { $expiration = (int) $expiration; /** * Filters a specific transient before its value is set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * @since 4.2.0 The `$expiration` parameter was added. * @since 4.4.0 The `$transient` parameter was added. * * @param mixed $value New value of transient. * @param int $expiration Time until expiration in seconds. * @param string $transient Transient name. */ $value = apply_filters( "pre_set_transient_{$transient}", $value, $expiration, $transient ); /** * Filters the expiration for a transient before its value is set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 4.4.0 * * @param int $expiration Time until expiration in seconds. Use 0 for no expiration. * @param mixed $value New value of transient. * @param string $transient Transient name. */ $expiration = apply_filters( "expiration_of_transient_{$transient}", $expiration, $value, $transient ); if ( wp_using_ext_object_cache() || wp_installing() ) { $result = wp_cache_set( $transient, $value, 'transient', $expiration ); } else { $transient_timeout = '_transient_timeout_' . $transient; $transient_option = '_transient_' . $transient; $custom_autoload_is_valid = null !== $custom_autoload && in_array( $custom_autoload,array( 'no','yes',true,false ) ); if ( false === get_option( $transient_option ) ) { $autoload = $custom_autoload_is_valid ? $custom_autoload : 'yes'; if ( $expiration ) { $autoload = $ccustom_autoload_is_valid ? $custom_autoload : 'no'; add_option( $transient_timeout, time() + $expiration, '', $autoload ); } $result = add_option( $transient_option, $value, '', $autoload ); } else { // If expiration is requested, but the transient has no timeout option, // delete, then re-create transient rather than update. $update = true; if ( $expiration ) { $autoload = $ccustom_autoload_is_valid ? $custom_autoload : 'no'; if ( false === get_option( $transient_timeout ) ) { delete_option( $transient_option ); add_option( $transient_timeout, time() + $expiration, '', $autoload ); $result = add_option( $transient_option, $value, '', $autoload ); $update = false; } else { update_option( $transient_timeout, time() + $expiration,$autoload ); } } if ( $update ) { $result = update_option( $transient_option, $value ); } } } if ( $result ) { /** * Fires after the value for a specific transient has been set. * * The dynamic portion of the hook name, `$transient`, refers to the transient name. * * @since 3.0.0 * @since 3.6.0 The `$value` and `$expiration` parameters were added. * @since 4.4.0 The `$transient` parameter was added. * * @param mixed $value Transient value. * @param int $expiration Time until expiration in seconds. * @param string $transient The name of the transient. */ do_action( "set_transient_{$transient}", $value, $expiration, $transient ); /** * Fires after the value for a transient has been set. * * @since 3.0.0 * @since 3.6.0 The `$value` and `$expiration` parameters were added. * * @param string $transient The name of the transient. * @param mixed $value Transient value. * @param int $expiration Time until expiration in seconds. */ do_action( 'setted_transient', $transient, $value, $expiration ); } return $result; }
Then, if I want to set a transient that expires for instance in 90 days, and I want the autoload (e.g. for a transient that is needed for 90 days and has to be autoloaded:
<?php set_transient( 'my_transient',$my_value, 60*60*24*90,'yes' );
Without any workaround and any additional code.
IF I want a transient without expiration but also without autoload (e.g. for a transient that is needed only in the backend:
<?php set_transient( 'my_transient',$my_value,false,'yes' );
Without workarounds and without additional code.
#5
follow-up:
↓ 10
@
2 years ago
- Keywords needs-patch added
@giuse if you could, please attach your suggested changes in the form of a patch or a pull request on GitHub. It's very difficult to see what is being changed from a full snippet.
#7
@
2 years ago
Related: #54221 is one example of where this might be useful in Core.
Temporary values should definitely not be autoloaded, but permanent ones can help save some time by being autoloaded.
The correlation between expiration of a transient and how many pages it's used on isn't obvious to me; can you articulate it?
#8
@
2 years ago
ticket:22844#comment:6 alludes to a discussion in the 2.8 development phase. I searched around, though, and didn't find anything on Make/Core or wp-hackers. The logs for #wordpress-dev only go back to 2009-05-14 (2.7 was released on 2008-12-10, and 2.8 on 2009-6-11).
The new Optimized Autoloaded Options proposal is related.
#9
@
13 months ago
I stumbled upon the same problem. I am getting some data from a third-party API that is needed for all front-end pages. I need this data to be valid, but I need to preserve it until the site does not get new data to avoid issues. So, I added a transient without expiration time and wanted to add another transient with expiration, but it turned out that it would not be autoloaded and would require an additional request to the DB. Finally, I decided to add a timestamp to the data I am receiving and save it in the same transient, but it would have been simpler just to check the second transient for existence.
#10
in reply to:
↑ 5
@
13 months ago
Replying to giuse:
Do you see any downsides in modifying the function with something like this?
I don't think there is a (significant) downside.
Also, your code refers to $ccustom_autoload_is_valid
, which should be $custom_autoload_is_valid
.
Replying to desrosj:
@giuse if you could, please attach your suggested changes in the form of a patch or a pull request on GitHub. It's very difficult to see what is being changed from a full snippet.
Since the suggested code is already in this ticket, can you help with this? Personally, I wouldn't know what to do.
This ticket was mentioned in PR #7502 on WordPress/wordpress-develop by @debarghyabanerjee.
2 months ago
#11
- Keywords has-patch added; needs-patch removed
Trac Ticket: Core-55969
## Overview
- This pull request introduces the $autoload argument to the set_transient function in WordPress. This enhancement allows developers to specify whether a transient should be autoloaded when the WordPress options are loaded.
## Changes Made
- New $autoload Parameter:
- The
set_transient
function now accepts a fourth parameter, $autoload, which determines if the transient should be included in the autoload process.
- The default value for $autoload is set to true, maintaining backward compatibility.
- Validation and Filtering:
- The code validates the $autoload parameter to ensure it is a boolean value, enhancing reliability.
- A filter is provided (autoload_transient_{$transient}) to allow developers to modify the autoload behavior if needed.
## Benefits:
- This enhancement provides greater control over transient storage, allowing developers to optimize performance by deciding which transients should be autoloaded.
- It aligns with the need for more granular performance tuning in WordPress applications.
The set_transient() manual states:
This seems to make sense. Temporary values should definitely not be autoloaded, but permanent ones can help save some time by being autoloaded.
I've just checked one of my sites and it has 14 autoloaded transients vs. 138 that aren't autoloaded.
You can find out about your own site using the following SQL query:
SELECT autoload, count(*) FROM wp_options WHERE option_name LIKE '_transient_%' group by autoload