Bot::BasicBot's forkit() creating zombies


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 ;)
 
Ad

Advertisements

R

Rocco Caputo

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.

It may be a bug in Bot::BasicBot. POE's SIGCHLD handling changed not
too long ago, and I don't know if Bot::BasicBot follows the new
recommendations.

The folks in irc.perl.org #poe may have better and/or deeper answers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top