- if ( $value === false ) {
- // Fetch the value over the network
- if ( isset( $opts['version'] ) ) {
- $version = $opts['version'];
- $asOf = null;
- $cur = $this->doGetWithSetCallback(
- $key,
+ if ( $version !== null ) {
+ $curAsOf = self::PASS_BY_REF;
+ $curValue = $this->doGetWithSetCallback(
+ $key,
+ $ttl,
+ // Wrap the value in an array with version metadata but hide it from $callback
+ function ( $oldValue, &$ttl, &$setOpts, $oldAsOf ) use ( $callback, $version ) {
+ if ( $this->isVersionedValue( $oldValue, $version ) ) {
+ $oldData = $oldValue[self::VFLD_DATA];
+ } else {
+ // VFLD_DATA is not set if an old, unversioned, key is present
+ $oldData = false;
+ $oldAsOf = null;
+ }
+
+ return [
+ self::VFLD_DATA => $callback( $oldData, $ttl, $setOpts, $oldAsOf ),
+ self::VFLD_VERSION => $version
+ ];
+ },
+ $opts,
+ $curAsOf
+ );
+ if ( $this->isVersionedValue( $curValue, $version ) ) {
+ // Current value has the requested version; use it
+ $value = $curValue[self::VFLD_DATA];
+ } else {
+ // Current value has a different version; use the variant key for this version.
+ // Regenerate the variant value if it is not newer than the main value at $key
+ // so that purges to they key propagate to the variant value.
+ $value = $this->doGetWithSetCallback(
+ $this->makeGlobalKey( 'WANCache-key-variant', md5( $key ), $version ),