継続でget_multiとかまとめたい。
memcachedのgetsとかJSONRPCのbulkリクエストとかを出来る限り透過的にまとめたい。
Apps::MemcachedはCache::Memcached::Fastのラッパーをイメージしてくだしあ。
Scope::Session::start { my $promised = Apps::Memcached::Promise->new; for my $c (1..5){ $promised->reserve(sub{ my $rand = 5; for( 1..$rand) { my $result = Apps::Memcached->new->get("hello:$c:$_"); ::ok "$c-$_ value"; } }); } $promised->join; };
こんなかんじで、getしか書いてないんだけど、その時点で
ステートを停止して、一通り検査し終えたところでgets!して、
復元して最後まで回すみたいなやつやりたい。
試しに書いてみた:
package Apps::Memcached::Promise; use strict; use warnings; use Apps::Memcached; use Coro; use Data::Util; sub new { return bless {},shift; } sub reserve { my ($self,$logic) = @_; $self->{_reserved} ||= []; push @{ $self->{_reserved} },$logic; } sub join { my ($self) = @_; no warnings qw/redefine/; my @keys; local *Apps::Memcached::get = Data::Util::modify_subroutine( Apps::Memcached->can('get'), around => [ sub { my ( $origin, $self, $key ) = @_; push @keys, $key; cede; return $origin->($self,$key); } ] ); my @reserved = @{ $self->{_reserved} }; my $wait = scalar @reserved; my @threads = map { my $logic = $_; async { cede; $logic->(); $wait--; }; } @{ $self->{_reserved} }; while( $wait){ cede; if( @keys){ Apps::Memcached->new->get_multi(@keys); warn "get_multi keys:". join ',',@keys; } @keys = (); } return ; } 1;
get_multi keys:hello:1:1,hello:2:1,hello:3:1,hello:4:1,hello:5:1 ok 1 ok 2 ok 3 ok 4 ok 5 get_multi keys:hello:1:2,hello:2:2,hello:3:2,hello:4:2,hello:5:2 ok 6 ok 7 ok 8 ok 9 ok 10 get_multi keys:hello:1:3,hello:2:3,hello:3:3,hello:4:3,hello:5:3 ok 11 ok 12 ok 13 ok 14 ok 15 get_multi keys:hello:1:4,hello:2:4,hello:3:4,hello:4:4,hello:5:4 ok 16 ok 17 ok 18 ok 19 ok 20 get_multi keys:hello:1:5,hello:2:5,hello:3:5,hello:4:5,hello:5:5 ok 21 ok 22 ok 23 ok 24 ok 25 1..25