Hello again,
How much time do you expect that to take?
I cannot express this in seconds or anything but as reading from any pipe
blocks until there is anything to read, I have to build in a mechanism that
shortens that waiting time. Whatever that is (I have at least something like
that already for another 'special' child) it takes much more longer to be
used 71 times than a single said:
After you chop it to remove the irrelevant parts, you need to sew it back
up again (and verify it still shows the problem).
I choped it as much as it was possible, but it did not yet show up the
error. May be I cut too much, but as the last run of my big script was fine
for 6 hours before the error appeared I think it is just not easy to
reproduce the error.
Anyway I put some code at the end of this message, which should run and show
at least how I work to send a message and use the pipe.
You could try "flock"ing the write handle before each write, but I doubt
that will help.
I do not have a clue how this could work, so I am willing to believe xhoster
that this does not really work with Linux (which I use). But this will work
with named pipes - so maybe I will just switch that type to see if the error
still exists.
I think this problem is much more complicated than you
think it is. Look into IO::Select.
That first sentence is not making an easy day

I had a look again to
IO::Select - what I tried to use to find out if my pipe is readable (which
was quite nonsense, as there is a difference between the shown 'open to
read' and the searched 'something in to be read'). I thought it might help
to use has_exception(), but it did not find any on the pipe, even directly
after there was a lost message. But maybe I just launched into that function
and did not recognize what you really wanted me to have a look at.
IO:

ipe is just a pretty layer over the built-in pipe(). Personally,
now that we have handle autovivification, I'd not bother and just say:
pipe(my $reader, my $writer) or die $!;
I cut that out and replaced it with IO:

ipe as this seemed to be working
with IO::Select (what seems to expect an object). But that seems obsolete
now anyway.
Anyhow - FIFOs should be lossless no matter how many writers there are.
I think you're right, that might be my next step to try.
Only thing left now is that I'm scared wether my errors do depend on
different writers to the same pipe or the amount of data waiting in the pipe
to be read. As the errors occuring yesterday after 6 hours where 5 in a
period of only one minute.
Anyway, thanks for your help, I have at least now some hints how to proceed!
******************************************************
These are the remains of my code. But please use with care. It is an endless
loop so you have to stop it manually and if it runs to long, it will have an
enormously amount of data in the pipe (this is because in original script
the line to be sent is assembled after a line of a logfile is read via tail.
In this version there is always the same line to be send, which is very fast
and does never have a break between lines).
Sadly I must say I did not yet received the error with this...
As logging of the script is nearly the same in my big one, I'd like to show
you what I got yesterday:
my_log>>>>>
Wed Jan 4 13:22:17 2006 script started 24687
[...]
Wed Jan 4 13:49:56 2006 log reader started for 3070: 14508
Wed Jan 4 19:40:27 2006 Server 3201: Missing message between 54 and 56
Wed Jan 4 19:40:27 2006 Server 1665: Missing message between 38 and 40
Wed Jan 4 19:40:30 2006 Server 4002: Missing message between 9 and 11
Wed Jan 4 19:40:40 2006 Server 3022: Missing message between 52 and 61
Wed Jan 4 19:55:25 2006 Server 3025: Missing message between 70 and 74
<<<<<
script>>>>>>>>>>>>>>>>>>>>>>>
#!/usr/bin/perl
use strict;
use warnings;
use IO:

ipe;
$|++;
####################################
##### Variable's declaration #####
####################################
my %avl_server_ports; # saves all servers for which we have
data incl. their portsprocess)
# first get the updated server list from db[...]
# to change number of created children change loop condition here
for(1..30){
$avl_server_ports{$_} = $_;
}
my $server; # name of the server to be processed (for
child processes)
my %proc_counter; # ID for the procs (used in child procs)
my $logFile; # contains the name of the logfile for this
script
my $msid = 1; # the message id used on child-side
my %mshash; # actual message id per server used on father
side
###########################
##### Main programm #####
###########################
writeLog('create');
# creation of pipes used to communicate with cmd-child and log-file readers
my $pipe_log = new IO:

ipe();
# start the initial creation of all log-file-readers
syncLFR();
$pipe_log->reader();
# starting of working routine
while(1){
# do some other things...
# read the next info about processes
logProcessing();
}
##### this is the task of a log-file-reader #####
###################################################
sub logReader{
my $server = shift;
writeLog("log reader started for $server: $$");
$pipe_log->writer();
# and ensure not to buffer
$pipe_log->autoflush(1);
my $sentence = "2005/08/16 02:00:44 pid 27009 compute end 2s 90+30us
211+0io 0+0net 0k 103pf\n";
while(1){
sendWithMsId($server.'::'.$sentence);
}# end of while 1
} # end of sub: logReader
##### fathers routine to get the processes out of the pipe and handle them
correct #####
##########################################################################################
sub logProcessing{
my $line = '';
my ($msg, $server);
eval {
local $SIG{ALRM} = sub { die "lesedauer" };
alarm(1);
$line = <$pipe_log>;
alarm(0);
};
return if ($line !~ /::/);
($msg, $server, $line) = split(/::/, $line);
if(!exists $mshash{$server}){
$mshash{$server} = $msg;
}else{
if($msg != $mshash{$server} +1){
writeLog("Server $server: Missing message between $mshash{$server} and
$msg");
}
$mshash{$server} = $msg;
}
} # end of sub: logProcessing
##### write the log file #####
###########################################
sub writeLog{
my ($msg) = @_;
# IF YOU DO NOT WANT TO HAVE A PRINT IN YOUR COMMAND LINE
# YOU CAN CHANGE COMMENTS HERE TO WRITE A LOGFILE INSTEAD
if($msg eq 'create'){
# #my $day = getTodaysDate();
# my $day = '2006/01/05';
# $day =~ s/\///g;
# my $count = 1;
#
# open(LS, "2>&1 ls log/log$day.* | ");
# while(<LS>){
# if(my ($c) = /log$day.(\d+)/){
# $count++ if($c == $count);
# }
# }
# close(LS);
# $logFile = "log/log".$day.".".$count;
# open(LOG, ">$logFile");
# print LOG localtime(time) . " script started $$\n";
# close(LOG);
print localtime(time) . " script started $$\n";
}
# write the message in the logfile
else{
# open(LOG, ">>$logFile");
# print LOG localtime(time) . " " . $msg . "\n";
# close(LOG);
print localtime(time) . " " . $msg . "\n";
}
}
##### sends messages to the father and adds a message ID #####
##############################################################
sub sendWithMsId{
my $info = shift;
print $pipe_log $msid.'::'.$info;
$msid++;
}
##### Synchronization of log-file-readers according to avl. servers #####
###########################################################################
sub syncLFR{
# start lfr for all servers, which were not in the list already
foreach my $newServer (keys %avl_server_ports){
my $server = $newServer;
my $forked_pid = fork();
# this is the new log-file-reader
if(!$forked_pid){
logReader($server);
exit(0);
}
}
} # end of sub: snycLFR