X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2Fcluster.pl;h=dd12a9dfe22dc564058cadadb463bde7994f281a;hb=f3b23f65ec3e143910ec6a6c36cfe1ab37f0338c;hp=e38e697fd17dfedff5a8c3ba274c143d822a1c38;hpb=0a6cbd253403c416abea676d1bc5fa581caeb354;p=spider.git diff --git a/perl/cluster.pl b/perl/cluster.pl index e38e697f..dd12a9df 100755 --- a/perl/cluster.pl +++ b/perl/cluster.pl @@ -59,17 +59,21 @@ use Geomag; use CmdAlias; use Filter; use Local; +use DXDb; +use Data::Dumper; + use Fcntl ':flock'; -use Carp; +use Carp qw(cluck); package main; @inqueue = (); # the main input queue, an array of hashes $systime = 0; # the time now (in seconds) -$version = "1.28"; # the version no of the software +$version = "1.35"; # the version no of the software $starttime = 0; # the starting time of the cluster $lockfn = "cluster.lock"; # lock file name +@outstanding_connects = (); # list of outstanding connects # handle disconnections sub disconnect @@ -89,6 +93,8 @@ sub already_conn sleep(1); dbg('chan', "-> Z $call bye\n"); $conn->send_now("Z$call|bye"); # this will cause 'client' to disconnect + sleep(1); + $conn->disconnect; } # handle incoming messages @@ -98,7 +104,9 @@ sub rec my $dxchan = DXChannel->get_by_cnum($conn); # get the dxconnnect object for this message if (defined $err && $err) { - disconnect($dxchan) if defined $dxchan; + if ($dxchan) { + disconnect($dxchan); + } return; } @@ -107,13 +115,14 @@ sub rec my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)\|(.*)$/; # is there one already connected to me ? - if ($dxchan = DXChannel->get($call)) { - disconnect($dxchan); - sleep(1); - } + my $user = DXUser->get($call); + if (DXChannel->get($call)) { + my $mess = DXM::msg($lang, $user->sort eq 'A' ? 'concluster' : 'conother', $call); + already_conn($conn, $call, $mess); + return; + } # is there one already connected elsewhere in the cluster (and not a cluster) - my $user = DXUser->get($call); if ($user) { if (($user->sort eq 'A' || $call eq $myalias) && !DXCluster->get_exact($call)) { ; @@ -144,6 +153,7 @@ sub rec # create the channel $dxchan = DXCommandmode->new($call, $conn, $user) if ($user->sort eq 'U'); $dxchan = DXProt->new($call, $conn, $user) if ($user->sort eq 'A'); + $dxchan = BBS->new($call, $conn, $user) if ($user->sort eq 'B'); die "Invalid sort of user on $call = $sort" if !$dxchan; } @@ -173,8 +183,22 @@ sub cease Local::finish(); # end local processing }; dbg('local', "Local::finish error $@") if $@; - + + # disconnect users foreach $dxchan (DXChannel->get_all()) { + next if $dxchan->is_ak1a; + disconnect($dxchan) unless $dxchan == $DXProt::me; + } + Msg->event_loop(1, 0.05); + Msg->event_loop(1, 0.05); + Msg->event_loop(1, 0.05); + Msg->event_loop(1, 0.05); + Msg->event_loop(1, 0.05); + Msg->event_loop(1, 0.05); + + # disconnect nodes + foreach $dxchan (DXChannel->get_all()) { + next unless $dxchan->is_ak1a; disconnect($dxchan) unless $dxchan == $DXProt::me; } Msg->event_loop(1, 0.05); @@ -190,9 +214,16 @@ sub cease Msg->event_loop(1, 0.05); Msg->event_loop(1, 0.05); DXUser::finish(); + + # close all databases + DXDb::closeall; + dbg('chan', "DXSpider version $version ended"); Log('cluster', "DXSpider V$version stopped"); + dbgclose(); + Logclose(); unlink $lockfn; +# $SIG{__WARN__} = $SIG{__DIE__} = sub {my $a = shift; cluck($a); }; exit(0); } @@ -201,6 +232,7 @@ sub reap { $SIG{'CHLD'} = \&reap; my $cpid = wait; + @outstanding_connects = grep {$_->{pid} != $cpid} @outstanding_connects; } # this is where the input queue is dealt with and things are dispatched off to other parts of @@ -212,23 +244,31 @@ sub process_inqueue my $data = $self->{data}; my $dxchan = $self->{dxchan}; - my ($sort, $call, $line) = $data =~ /^(\w)(\S+)\|(.*)$/; + my ($sort, $call, $line) = $data =~ /^(\w)([A-Z0-9\-]+)\|(.*)$/; + my $error; + + # the above regexp must work + return unless ($sort && $call && $line); + + # translate any crappy characters into hex characters + if ($line =~ /[\x00-\x06\x08\x0a-\x1f\x7f-\xff]/o) { + $line =~ s/([\x00-\x1f\x7f-\xff])/uc sprintf("%%%02x",ord($1))/eg; + } # do the really sexy console interface bit! (Who is going to do the TK interface then?) dbg('chan', "<- $sort $call $line\n") unless $sort eq 'D'; - + # handle A records my $user = $dxchan->user; if ($sort eq 'A' || $sort eq 'O') { $dxchan->start($line, $sort); } elsif ($sort eq 'I') { die "\$user not defined for $call" if !defined $user; - # normal input $dxchan->normal($line); - disconnect($dxchan) if ($dxchan->{state} eq 'bye'); } elsif ($sort eq 'Z') { + $dxchan->conn(undef); disconnect($dxchan); } elsif ($sort eq 'D') { ; # ignored (an echo) @@ -256,6 +296,7 @@ sub uptime $starttime = $systime = time; # open the debug file, set various FHs to be unbuffered +dbginit(); foreach (@debug) { dbgadd($_); } @@ -317,6 +358,10 @@ DXMsg::clean_old(); print "reading cron jobs ...\n"; DXCron->init(); +# read in database descriptors +print "reading database descriptors ...\n"; +DXDb::load(); + # starting local stuff print "doing local initialisation ...\n"; eval { @@ -332,7 +377,7 @@ print "orft we jolly well go ...\n"; dbg('chan', "DXSpider version $version started..."); for (;;) { my $timenow; - Msg->event_loop(1, 0.001); + Msg->event_loop(1, 0.1); $timenow = time; process_inqueue(); # read in lines from the input queue and despatch them @@ -345,6 +390,8 @@ for (;;) { DXCommandmode::process(); # process ongoing command mode stuff DXProt::process(); # process ongoing ak1a pcxx stuff DXConnect::process(); + DXMsg::process(); + DXDb::process(); eval { Local::process(); # do any localised processing };