I'm setting up a pair of web servers to have failover redundancy. If the main server fails, the backup server takes over.
I'm trying to automate testing of my prototype. I figure I'll need two pieces, a "observer" that sits on a client machine and watches and coordinates the action, gathers results etc... Then I'll need a "gremlin". There will actually be two gremlins, one on each server. The gremlins will cause failures and forward internal information to the observer.
Actual QuestionWhats a good way to facilitate the communication between those three guys? Quick and easy is my highest priority. This will only run in my test lab (I don't want gremlins causing failures on my real servers) so stability and security aren't a big priority.
The observer needs to be able to tell the gremlins when to cause failures. The gremlins need to confer among themselves to coordinate the failures. The gremlins also need to be able to tell the observer all kinds of status info about the server that gremlin is running on.
Thanks Monks!
-Pileofrogs
Observer
Also, if you look closely, you'll see where I didn't put any real error checking :) I leave that to you ;)
this should give you a start. You could have your gremlins connect to each other if they need to chat with each other, the server model is probably simpler, though.
make sense?
use strict;
use IO::Socket::INET;
use IO::Select;
my $sock = IO::Socket::INET->new(LocalPort => 4455, Listen => 5);
my $select = IO::Select->new($sock);
my %gremlins; # list of gremlins!
for(;;) { #mainloop
if(my @socks = $select->can_read(0)) { #non-blocking check for data
for my $gremlin (@socks) {
if($gremlin eq $sock) { # connection
my $c = $sock->accept();
next unless $c;
my $init = <$c>;
chomp $init;
$gremlins{$c} = [$c,$init]; # can't store actual ref as key
print "Added gremlin $init\n";
$select->add($c); # add to list of sockets
} else {
if($gremlin->eof()) { #child died!
print "Gremlin $gremlins{$gremlin}[1] died\n";
$select->remove($gremlin);
delete $gremlins{$gremlin};
next;
}
#message for you, sire!
my $msg = <$gremlin>;
chomp $msg;
print "Got message '$msg', sending to gremlins\n";
for(keys %gremlins) {
next if $_ eq $gremlin; #dont send the message to sender
my $c = $gremlins{$_}[0]; #sock of peer
print $c "$gremlins{$_}[1]: $msg\n"; #send to other gremlins everything we get, as an exercise
}
}
}
}
sleep 1;
}
and
Gremlin
use strict;
use IO::Socket::INET;
use IO::Select;
my $sock = IO::Socket::INET->new(PeerAddr => "localhost:4455");
print $sock "Pid $$\n"; # the init string, used as a 'name' for this client, you may want something more descriptive/informative etc.
my $select = IO::Select->new($sock);
my $i = 0;
for(;;) { #main loop
unless(int(rand(5))) {
my $msg = "It has been $i iterations since I last sent something\n";
print "Sending message: $msg";
print $sock $msg;
$i=0;
}
if($select->can_read(0)) { #could capture sockets, but there is only one
die "observer gone\n" if $sock->eof();
print "Got a message:\n ".<$sock>;
}
$i++;
sleep 1;
}
Now, I just threw these together, but they do work. You would obvoiusly have to work your own code in here somehow rather than my sleep 1;
perlmonks.org content © perlmonks.org and astroboy, pileofrogs, suaveant, zentara
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03