tags:

views:

169

answers:

1

I'm currently writing an IRC bot. The scripts are loaded as perl modules in ZNC but the bot gets disconnected with an Input/Output error if I create a forked process. This is a working example script without fork, but this causes the bot to freeze until the script finishes doing its task.

package imdb;

use warnings;
use strict;


sub new
{
 my ($class) = @_;
 my $self = {};

 bless( $self, $class );
 return( $self );
}

sub OnChanMsg 
{
 my ($self, $nick, $channel,$text) = @_;

#unless (my $pid = fork()) {

 my $result = a_slow_process($text); 
 ZNC::PutIRC( "PRIVMSG $channel :$result" );
# exit;
#}

 return( ZNC::CONTINUE );

}

sub OnShutdown
{
 my ( $me ) = @_;
}

sub a_slow_process { 
my $input = shift; 
sleep 10; 
return "You said $input.";
 }

1;

The fork code that is causing the error is commented out. How do I fix this?

Edited to add: I was told that ZNC::PutIRC should not be put in the child process.

+1  A: 

A fork() call has effects on open file and socket handles, including:

File descriptors (and sometimes locks on those descriptors) are shared, while everything else is copied.

...

Beginning with v5.6.0, Perl will attempt to flush all files opened for output before forking the child process, but this may not be supported on some platforms (see perlport). To be safe, you may need to set $| ($AUTOFLUSH in English) or call the "autoflush()" method of "IO::Handle" on any open handles in order to avoid duplicate output.

and in general it is not a good idea to set up a socket connection in one process and try to read/write on that connection in a child process.

A workaround might be to make a new ZNC connection in the child process (after a_slow_process() is done), write your private message, and then close the new connection.

mobrule
Can you show me an example script with IO::Handle?A new connection will lag a bit after it connects (especially if the bot is on a lot of channels), thus defeating the purpose of forking.
rarbox