web-dev-qa-db-ja.com

外部オブジェクトキャッシュを使用している場合、キャッシュされたプラグインデータを消去する

私はそれが使用するデータのいくつかをキャッシュするプラグインを作成しました - 主にSalesforce REST AP​​I呼び出し結果、そして定期的にそれらを期限切れにします(デフォルトでは24時間ごと)。

プラグインはこれらのメソッドを呼び出してキャッシュを制御します。

/**
 * Check to see if this API call exists in the cache
 * if it does, return the transient for that key
 *
 * @param string $url The API call we'd like to make.
 * @param array  $args The arguents of the API call.
 * @return get_transient $cachekey
 */
public function cache_get( $url, $args ) {
    if ( is_array( $args ) ) {
        $args[] = $url;
        array_multisort( $args );
    } else {
        $args .= $url;
    }
    $prefix = esc_sql( $this->transient_prefix() );
    $cachekey = $prefix . md5( wp_json_encode( $args ) );
    return get_transient( $cachekey );
}

/**
 * Create a cache entry for the current result, with the url and args as the key
 *
 * @param string $url The API query URL.
 * @param array  $args The arguments passed on the API query.
 * @param array  $data The data received.
 * @param string $cache_expiration How long to keep the cache result around for.
 * @return Bool whether or not the value was set
 * @link https://developer.wordpress.org/reference/functions/set_transient/
 */
public function cache_set( $url, $args, $data, $cache_expiration = '' ) {
    if ( is_array( $args ) ) {
        $args[] = $url;
        array_multisort( $args );
    } else {
        $args .= $url;
    }
    $prefix = esc_sql( $this->transient_prefix() );
    $cachekey = $prefix . md5( wp_json_encode( $args ) );
    // Cache_expiration is how long it should be stored in the cache.
    // If we didn't give a custom one, use the default.
    if ( '' === $cache_expiration ) {
        $cache_expiration = $this->options['cache_expiration'];
    }
    return set_transient( $cachekey, $data, $cache_expiration );
}

/**
 * Get the cache transient prefix for this plugin and return it
 *
 * @return The transient prefix
 */
private function transient_prefix() {
    $transient_prefix = 'sfwp';
    return $transient_prefix;
}

/**
 * If there is a WordPress setting for how long to keep this specific cache, return it and set the object property
 * Otherwise, return seconds in 24 hours
 *
 * @param string $option_key The cache item to keep around.
 * @param int    $expire The default time after which to expire the cache.
 * @return The cache expiration saved in the database.
 */
public function cache_expiration( $option_key, $expire ) {
    $cache_expiration = get_option( $option_key, $expire );
    return $cache_expiration;
}

ただし、Salesforceオブジェクトの設定を変更し、自動期限切れを待ちたくない場合は、このキャッシュを手動で消去する方法をユーザに提供したいと思います。私はこのイベントでサイト全体のキャッシュをクリアしないようにしたいのですが(これはwp_cache_flush()が何をするかについての私の理解です)。

私は、サイトがトランジェントAPIを使用しているだけならこれは簡単だろうと思っているので、上記のメソッドに$transient_prefixを追加しました。しかし、それらがオブジェクトキャッシュを使用しているのであれば、私はリーグ外です。

私はこのようなcache_purgeメソッドを作成しました:

/**
 * Create a cache entry for the current result, with the url and args as the key
 *
 * @param string $subset If we only want to purge WordPress data, Salesforce data, options, etc.
 * @return Bool whether or not the purge was successful
 */
public function cache_purge( $subset = '' ) {
    $prefix = esc_sql( $this->transient_prefix() );

    // cache is stored somewhere other than the options table
    if ( wp_using_ext_object_cache() ) {

    } else {
        // cache is stored in the options table. this is pretty easy.
        $options = $this->wpdb->options;
        $t = esc_sql( '_transient_timeout_' . $prefix . '%' );
        $sql = $wpdb ->prepare( "SELECT option_name FROM $options WHERE option_name LIKE '%s'", $t );
        $transients = $this->wpdb->get_col( $sql );
        foreach ( $transients as $transient ) {
            // Strip away the WordPress prefix in order to arrive at the transient key.
            $key = str_replace( '_transient_timeout_', '', $transient );
            // Now that we have the key, use WordPress core to the delete the transient.
            delete_transient( $key );
        }
    }
}

私の理解するところでは、これによって外部オブジェクトキャッシュ(Varnish/memcacheなどと同様にキャッシングプラグインをカバーすると思います)の存在をチェックすることができ、トランジエントAPIがない場合はクリアします。

私はこれまでのところ正しいですか?もしそうなら、オブジェクトキャッシュから同じデータをクリアするために何ができますか?

1

object-cache.phpドロップインファイルを使用する場合、トランジェントAPIオブジェクトキャッシュAPIを使用します。

例えばwp_using_ext_object_cache()trueを返す場合、

get_transient( $transient ) 
-> wp_cache_get( $transient, 'transient' )

set_transient( $transient, $value, $expiration ) 
-> wp_cache_set( $transient, $value, 'transient', $expiration )

delete_transient( $transient ) 
-> wp_cache_delete( $transient, 'transient' )

ここで、グループはtransientです。

オブジェクトキャッシュAPIはグループによるキャッシュ削除のためのwp_cache_delete_group()をサポートしておらず、現在チケットにwontfixがあります #4476

そこに与えられた理由はすべての永続的なキャッシュソリューションがそれをサポートするというわけではないということでした。しかし、チケットに記述されている方法がいくつかあります。それはキャッシュソリューションに依存します。

例として、 WP Redis 永続オブジェクトキャッシュ実装はwp_cache_delete_group()をサポートしますが、 Memcached Object Cache 実装はサポートしません。

私たちのプラグインで永続オブジェクトキャッシュを使ってトランジェントを使うのであれば、次のことに注意してください。

if( function_exists( 'wp_cache_delete_group' ) )
{
    wp_cache_delete_group( 'transient' );
}

それから、私たち自身のプラグインで設定されたものだけでなく、すべてのトランジェントをフラッシュするように見えます。

キャッシュキーが事前にわかっている場合は、次のように削除します。

wp_cache_delete( $cachekey, $cachegroup );

トランジェントを使用した場合、$cachegroup'transient'です。

1
birgire