Hallo,
sicher habt ihr noch meine Speicherprobleme mit xerces,soap und Co.
in Erinnerung.
Da sich hier in absehbarer Zeit keine Änderung abzeichnet, muss ich
das Problem von der anderen Seite angehen.
So gibt es jetzt einen Control-Prozess, der u.a. den
Speicherverbrauch meines schlimmen Fingers überwacht. Bei einer
einstellbaren Grenze gibts ein kill() und danach wird der Prozess neu
gestartet. Eigentlich ganz einfach, aber hier komt der Haken:
Ich starte das Program mit 'nohup ./soapserver.pl &' sowohl von der
Kommandozeile als auch aus meinem Control-Programm heraus (hier über
system).
Das gestartet Programm mach einen Port 8081 auf, um zu lauschen. Beim
Start aus dem Control-Programm heraus erhalte ich aber die Meldung:
Can't create daemon: Die Adresse wird bereits verwendet at
/home/interface/bidi/soapserver.pl line 23
Hmm. Das er beim kill() nicht gleich freigegeben wird, kann ja mal
passieren, darum habe ich noch ein sleep(5) zwischen Kill und Start
eingebaut. Hilft nix.
Es geistert auch kein Zombi in der Prozessliste rum.
Mache ich kill und Start über die Shell, brauche ich keine Wartezeit
einplanen, der Start klappt immer sofort.
Also, was läuft hier falsch und wie mache ich es richtig? Anbei die
drei subs. watchMemory() läuft dabei immer als eigener Process, weil
vom Controller geforkt.
########## die Überwachungsroutine ##############################
sub watchMemory{
# überwacht Speicherverbrauch vom soapserver.pl und startet ihn
bei Bedarf neu
my %env_fake; # Start und Stop wollen den Dienstnamen in einem Hash
$env_fake{dienst} = "interface";
while(1){
my %res = &getServerInfo();
#print Dumper(%res);
if($res{i_online} == 0 ) {
print STDERR "Kein Serverprozess da .... \n";
sleep(10);
next;
}
if ($res{i_memory} > $limit && $res{i_status} eq 'sleep'){
print STDERR " zu hoch (max: $limit) .... starte neu ....
\n";
&stopServer(\%env_fake);
sleep(2); # bissel warten, bis Port wieder freigegeben wird
&startServer(\%env_fake);
}
sleep(10);
}
}
############### Stoppen ####################
sub stopServer{
# Stoppt soapsever oder connector
my $env = shift;
my $pattern = $map{ $env->{dienst} }.".pl";
# keine Pattern gefunden? -> raus !!
if($pattern eq '.pl'){return;}
my $kill = 0; # counter
my $t = new Proc::ProcessTable;
foreach my $p(@{$t->table}){
$kill += $p->kill(15) if $p->cmndline =~ /$pattern/ ;
}
my $res = &getStatus;
return $res;
}
################# Starten ###################
sub startServer{
# starten soapserer oder connector
my $env = shift;
if( $map{ $env->{dienst} } eq "soapserver" ){
system ("nohup /home/interface/bidi/soapserver.pl &");
}elsif( $map{ $env->{dienst} } eq "connector" ){
system ("nohup /home/interface/bidi/connector.pl &");
}
my $res = &getStatus;
return $res;
}
Mit freundlichen Grüßen
Jens Puruckherr