Gearman で遊んでたら思いついたので書いておきます。ネタに近い。
複数台のマシンで同じコマンドを実行して結果を見たい、てなのを Gearman でやってみる。
- worker: 自分の hostname を function 名として job server に登録。job の引数に受け取った文字列を shell に食わせて実行する
- client: worker の動いているマシンの hostname を function 名として、実行したい shell command を投げる
てなかんじ。
あらかじめ job_server になるマシンは決めて gearmand を実行しておき、コマンドを実行したいマシンで worker.pl を起動。
$ perl worker.pl sola # 引数は job_server名 job_server: sola myhostname: sola
$ perl gworker.pl sola job_server: sola myhostname: white.internal
client.pl を実行してコマンド送信すると、
$ perl client.pl sola white.internal sola # 最初の引数がjob_server、以降がworkerのmyhostnameで表示されるホスト名 job_server: sola hostnames : white.internal sola > uptime ==== sola ==== 03:20:58 up 211 days, 22:52, 1 user, load average: 0.00, 0.10, 0.10 ==== white.internal ==== 3:20 up 62 days, 27 mins, 4 users, load averages: 0.09 0.12 0.11 > uname -a ==== sola ==== Linux sola 2.6.19-gentoo-r5 #1 SMP PREEMPT Thu Feb 15 17:40:12 JST 2007 i686 Intel(R) Pentium(R) M processor 1.60GHz GenuineIntel GNU/Linux ==== white.internal ==== Darwin white.internal 8.10.1 Darwin Kernel Version 8.10.1: Wed May 23 16:33:00 PDT 2007; root:xnu-792.22.5~1/RELEASE_I386 i386 i386
こうなる。
手間がかかる割には面白くなかったような……
#!/usr/bin/perl # worker.pl use strict; use Gearman::Worker; use Sys::Hostname; use Perl6::Say; my $job_server = shift || die "no job server\n"; my $hostname = hostname(); say "job_server: $job_server"; say "myhostname: $hostname"; my $worker = Gearman::Worker->new; $worker->job_servers($job_server); $worker->register_function( $hostname => sub { my $job = shift; my $command = $job->arg; return qx{ $command }; }, ); $worker->work while 1;
#!/usr/bin/perl # client.pl use strict; use Gearman::Client; use Perl6::Say; my $timeout = 30; my ( $job_server, @hostname ) = @ARGV; die "no job server\n" unless $job_server; say "job_server: $job_server"; say "hostnames : @hostname"; my $client = Gearman::Client->new; $client->job_servers($job_server); while (1) { print "> "; my $cmd = <STDIN>; chomp $cmd; my $taskset = $client->new_task_set; for my $h (@hostname) { $taskset->add_task( $h => \$cmd, { on_complete => sub { say "==== $h ===="; say ${ $_[0] }; }, } ); } $taskset->wait( timeout => $timeout ); }