Cache::Memcached::Fastでexpireせず

setメソッドの第3引数(expiration time)にReadonlyな変数をセットすると、なぜかexpireしないというbugに当たって、えらく苦労したのでそのまとめ。

再現方法

試したバージョンは以下の通り。

  • memcached 1.2.6
  • Cache::Memcached::Fast 0.14


ローカルの11211ポートで動いているmemcachedに対して、600秒後にexpireするようset。

perl -MReadonly -MCache::Memcached::Fast -le '$c=Cache::Memcached::Fast->new(+{servers=>[+{address=>"localhost:11211"}]}); Readonly my $ttl => 600; $c->set("Readonly", "Readonly", $ttl)'

確認方法

statsコマンドを使ってキャッシュをdumpし、expiration timeを調べる

perl -MData::Dumper -MCache::Memcached -le '$c=Cache::Memcached->new(+{servers=>["localhost:11211"]}); $s=$c->stats("cachedump 1 100")->{hosts}{"localhost:11211"}; print Dumper $s'

statsコマンドからtimeとuptimeの差(=memcachedの起動時刻)を求める

perl -MTime::Piece -MCache::Memcached -le '$c=Cache::Memcached->new(+{servers=>["localhost:11211"]}); $misc=$c->stats("misc")->{hosts}{"localhost:11211"}{misc}; $t=localtime($misc->{time}-$misc->{uptime}); print $t->epoch'

これら2つが一致していたら、有効期限のないcacheとなる

CHANGESでbugを調べる

http://cpansearch.perl.org/src/KROKI/Cache-Memcached-Fast-0.19/Changes


CHANGES

0.18 2010-04-06
- make module thread-safe, and fix several bugs. No need to
upgrade unless you experienced limitations mentioned below.

Changes since 0.17:

Fix RT#56142: handle Perl magic. Tied scalars, arrays and
hashes are supported now, as well as Readonly variables and
other magic stuff.

まさにこのケース!!
ここに辿り着くまではだいぶ大変だったものの、Lazy Expirationを調べたり、キャッシュダンプする方法を知れたりと、色々勉強になりました。