M
Marko Vihoma
Hello all.
First of all I'd like to tell you all that I'm a total Perl newbie, just
have read the excellent and fun "Learning Perl" and a bit of
"Programming Perl" in finnish...
I have created an IRC bot based on Bot::BasicBot, but when I use the
Bot::BasicBot's forkit() method to run for example a Yahoo! search in
the background (which I had created a subroutine for in my bot class),
it created a zombie perl process at each invocation (at least on OpenBSD
4.2 and OS X 10.4.11) and I have strict process limits for my bot's
user. For this reason I don't have forkit() in my bot
(http://personal.inet.fi/koti/marko.vihoma/src/LokkiBot.pl) anymore.
I believe forkit is using POE::Wheel::Run behind the curtains to do the
background job. Does anybody know how should I use forkit() to run a
subroutine without creating zombies? With standard fork() I should use
waitpid($pid) to wait for the processes completion, but I don't have
that option with Bot::BasicBot's forkit() as AFAIK it doesn't return the
PID of the forked process.
My code looked something like this before I stopped using forkit()
method in my code:
-- BEGIN code --
# Said is run every time somenone says something on a channel or in a
privmsg.
sub said {
my $self = shift;
my $message = shift;
my $reply = undef;
my $body = $message->{body};
my $channel = $message->{channel};
my $server = $self->{server};
my $who = $message->{who};
if ($message->{address}) {
if ($body =~ /^yahoo/) {
$body =~ s/^yahoo (.+)$/$1/;
$self->forkit(
run => \&yahoo, arguments => [$body], $who => $who,
channel => 'msg'
);
}
}
}
# &yahoo returns top five results from a Yahoo! search through Yahoo!
# search API.
sub yahoo {
shift;
my $query = shift;
my @content;
my $err = "En suanunna haettua \n";
print $err and return if (not $query);
my @res;
my $reply;
my $ua = LWP::UserAgent->new();
$ua->agent($agent);
my $response = $ua->get(
"http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=" .
"${yid}&query=${query}&results=${yahoo_results}"
);
if ($response->is_success) {
my $content = $response->content;
@content = split("\n", $content);
}
else {
print $err;
return;
}
my $n = 0;
for my $line (@content) {
print "Sori, mut hakulimitti on tullunna vastaan" .
" Yritä myöhemmin uudestaan.\n" and return if
($line =~ /^<Error/);
if ($line =~ /<Result><Title>/) {
$line =~
s/^.+?<Title>(.+?)<\/Title>.+?<Url>(.+?)<\/Url>.*$/$1<$2>/;
$res[$n++] = $line;
}
}
if (@res) {
$reply = "1. $res[0]\n";
for my $n (1..4) {
$reply .= $n+1 . ". $res[$n]\n";
}
print $reply;
return;
}
else {
print $err;
return;
}
}
-- END code --
If anyone has any experience with Bot::BasicBot, I would be glad to hear
how to run forkit() without creating zombies and if this is a bug in
Bot::BasicBot.
"Parents were stuck and had to be killed" -- talk about zombies at
comp.unix.bsd.freebsd.misc
First of all I'd like to tell you all that I'm a total Perl newbie, just
have read the excellent and fun "Learning Perl" and a bit of
"Programming Perl" in finnish...
I have created an IRC bot based on Bot::BasicBot, but when I use the
Bot::BasicBot's forkit() method to run for example a Yahoo! search in
the background (which I had created a subroutine for in my bot class),
it created a zombie perl process at each invocation (at least on OpenBSD
4.2 and OS X 10.4.11) and I have strict process limits for my bot's
user. For this reason I don't have forkit() in my bot
(http://personal.inet.fi/koti/marko.vihoma/src/LokkiBot.pl) anymore.
I believe forkit is using POE::Wheel::Run behind the curtains to do the
background job. Does anybody know how should I use forkit() to run a
subroutine without creating zombies? With standard fork() I should use
waitpid($pid) to wait for the processes completion, but I don't have
that option with Bot::BasicBot's forkit() as AFAIK it doesn't return the
PID of the forked process.
My code looked something like this before I stopped using forkit()
method in my code:
-- BEGIN code --
# Said is run every time somenone says something on a channel or in a
privmsg.
sub said {
my $self = shift;
my $message = shift;
my $reply = undef;
my $body = $message->{body};
my $channel = $message->{channel};
my $server = $self->{server};
my $who = $message->{who};
if ($message->{address}) {
if ($body =~ /^yahoo/) {
$body =~ s/^yahoo (.+)$/$1/;
$self->forkit(
run => \&yahoo, arguments => [$body], $who => $who,
channel => 'msg'
);
}
}
}
# &yahoo returns top five results from a Yahoo! search through Yahoo!
# search API.
sub yahoo {
shift;
my $query = shift;
my @content;
my $err = "En suanunna haettua \n";
print $err and return if (not $query);
my @res;
my $reply;
my $ua = LWP::UserAgent->new();
$ua->agent($agent);
my $response = $ua->get(
"http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=" .
"${yid}&query=${query}&results=${yahoo_results}"
);
if ($response->is_success) {
my $content = $response->content;
@content = split("\n", $content);
}
else {
print $err;
return;
}
my $n = 0;
for my $line (@content) {
print "Sori, mut hakulimitti on tullunna vastaan" .
" Yritä myöhemmin uudestaan.\n" and return if
($line =~ /^<Error/);
if ($line =~ /<Result><Title>/) {
$line =~
s/^.+?<Title>(.+?)<\/Title>.+?<Url>(.+?)<\/Url>.*$/$1<$2>/;
$res[$n++] = $line;
}
}
if (@res) {
$reply = "1. $res[0]\n";
for my $n (1..4) {
$reply .= $n+1 . ". $res[$n]\n";
}
print $reply;
return;
}
else {
print $err;
return;
}
}
-- END code --
If anyone has any experience with Bot::BasicBot, I would be glad to hear
how to run forkit() without creating zombies and if this is a bug in
Bot::BasicBot.
"Parents were stuck and had to be killed" -- talk about zombies at
comp.unix.bsd.freebsd.misc