my ($readHandle, $writeHandle) = (IO::Handle->new, IO::Handle->new);
my $pid = open2($readHandle, $writeHandle, @command);
$readHandle->autoflush(1);
$readHandle->blocking(0);
$writeHandle->autoflush(1);
$writeHandle->blocking(0);
####
## $messageForProcessing is a data structure stored as a hash reference
my $frozenMessage = freeze($messageForProcessing);
print $writeHandle $frozenMessage . qq|\n| . $this->_messageDelimiter();
####
sub processMessages
{
my ($this) = @_;
my $endTime = time + $ENV{'MAX_LIFETIME'};
select STDOUT;
$|++; # make unbuffered
my $select = IO::Select->new();
$select->add(\*STDIN);
my $messageDelimiter = $this->_messageDelimiter();
my $delimiterMatch = qr{\n$messageDelimiter$};
my $frozenMessage;
my $messageToProcess = {};
my $stopNow = 0;
while(time < $endTime)
{
my $offset;
my ($handle) = $select->can_read(5);
my $previousRead;
while(
($handle)
&&
(my $bytes = $handle->sysread($frozenMessage, 8192, $offset))
)
{
$offset += $bytes;
## Because Storable may put newlines in the frozen object,
## delimit messages:
my $searchableText = $previousRead . $frozenMessage;
if($searchableText =~ /$delimiterMatch/)
{
$frozenMessage =~ s/$delimiterMatch//;
$messageToProcess = thaw($frozenMessage);
}
$previousRead = $frozenMessage;
if(%$messageToProcess)
{
### DO MESSAGE PROCESSING HERE ##
my $outputMessage;
if($processor->hasErrors())
{
my $errors = $processor->getErrors();
$outputMessage = qq|$$ ERROR $errors->[0]\n|;
}
else
{
my $messageID = $processor->lastMessageID();
$outputMessage = qq|$$ SUCCESS $messageID\n|;
}
## Write status back to the parent
print STDOUT $outputMessage;
$offset = 0;
undef($frozenMessage);
undef($previousRead);
undef(%$messageToProcess);
}
}
}
}
####
Process 22515 attached - interrupt to quit
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0
select(8, [0], NULL, NULL, {5, 0}) = 1 (in [0], left {5, 0})
read(0, "", 8192) = 0