11. 結果 Hello World '1‘ Hello World '2‘ Hello World '3‘ Hello World '4‘ Hello World '5‘ --- ここまでが4秒後にドバっと出てくる Hello World '1‘ Hello World '2‘ Hello World '3‘ Hello World '4‘ Hello World '5‘ --- ここまでが4秒後にドバっと出てくる 以降繰り返し YAPC::Asia 2010
12. HelloWorldストリーミング with CGI (long-polling 対応版) #!perl open my $fh, '<', 'counter.txt'; my $count = <$fh>; close $fh; $count++; open my $fh, '>', 'counter.txt'; print $fh $count; close $fh; print "Content-Type: text/html"; print "<h2>Hello World '$count'</h2>"; YAPC::Asia 2010
39. 三つの下僕 その2: GearmanHello World with Gearman ジョブを定義する ジョブクラス: MyJobs.pm hello を秒間1回、計5回出力する。job_* で始まる単なる関数 package MyJobs; subjob_hello { my $job = shift; my $arg = $job->arg; # クライアントが設定した引数 for (1..5) { print "hello $arg $_"; sleep 1; $job->set_status($_, 5); # 進捗ステータスを更新 } return “finished:$arg”; # 完了したらリターン } 1; YAPC::Asia 2010
40. 三つの下僕 その2: Gearmanワーカーサーバー #1 use strict; use warnings; use Gearman::Worker;# 同期式ワーカーライブラリ use Getopt::Long; use Parallel::Prefork; use Pod::Usage; use UNIVERSAL::require; use Class::Inspector; use Data::Dumper; my $max_workers = 10; GetOptions( 's|server=s@‘ => y $servers, 'prefix=s‘ => y $prefix, 'max-workers=i‘ => max_workers, 'h|help‘ => y $help, ) or pod2usage(); pod2usage() unless $servers && @$servers; pod2usage() if $help; YAPC::Asia 2010
41. 三つの下僕 その2: Gearmanワーカーサーバー #2 my $worker = Gearman::Worker->new(); $worker->job_servers(@$servers); #サーバーのIPを登録する $worker->prefix($prefix) if $prefix; for my $klass (@ARGV) { $klass->use or die $@; my @jobs = grep /^job_/, @{ Class::Inspector->functions($klass) }; for my $job (@jobs) { ( my $job_name = $job ) =~ s/^job_//; # ジョブを登録する $worker->register_function( $job_name, $klass->can($job) ); } } YAPC::Asia 2010
42. 三つの下僕 その2: Gearmanワーカーサーバー #3 my $pm = Parallel::Prefork->new({ max_workers => $max_workers, trap_signals => { TERM => 'TERM', HUP => 'TERM', USR1 => undef, }, }); while ( $pm->signal_received ne 'TERM' ) { $pm->start and next; $worker->work; # ジョブを実行する $pm->finish; } $pm->wait_all_children(); YAPC::Asia 2010
43. 三つの下僕 その2: Gearmanクライアント use AnyEvent::Gearman; # 非同期クライアントライブラリ my $cv = AE::cv; my $client = gearman_client '127.0.0.1:4730'; for (1..10) { $cv->begin; $client->add_task( hello => “[$_]”, # ジョブ名 => 引数 on_complete => sub { # ジョブの戻り値を受け取ることができる my $result = $_[1]; print "complete => $result"; $cv->end; }, on_status => sub { # ジョブの進捗状況を受け取ることができる my ($self, $n, $d) = @_; print "status => $n:$d"; }, ); } $cv->recv; # タスクの終了を待ち受ける必要がある YAPC::Asia 2010