memcached の get_multi

memcached の get_multi をみんなどうやって使ってるのかな、と思っていろいろ教えてもらいました。#soozyのみなさん、twitterのみなさん、ありがとうございます。自分的にはこんな感じなのかな、と思いました (別にクロージャじゃなくてクラスでもいいけど)。

sub get1 {
    ...
    return {
        key_name => ...,
        getter   => sub {
            ...
        },
    };
}

sub get2 {
    ...
    return {
        key_name => ...,
        getter   => sub {
            ...
        },
    };
}

...

$tt->process('hoge.html', get_multi_refill({
    cached => {
        cached1 => get1(...),
        cached2 => get2(...),
    },
    direct => {
        direct1 => 'hoge',
        direct2 => 'foo',
    }),
);

sub get_multi_refill {
    my $vars = shift;
    my $result = $vars->{direct};
    
    # get_muti
    my $got = $cache->get_multi(
        map { $vars->{cached}->{$_}->{key_name} } keys $vars->{cached},
    );
    # get items not found in cache, as well as storing them in cache
    foreach my $n (keys $vars->{cached}) {
        if ($got->{$n}) {
            $result->{$n} = $got->{$n};
        } else {
            my $v = $vars->{$n}->getter->();
            $cache->set($vars->{$n}->{key_name}, $v);
            $result->{$n} = $v;
        }
    }
    
    $result;
}