Rearrange startup PC92 arrangements
authorDirk Koopman <djk@tobit.co.uk>
Sat, 23 Jun 2007 11:54:02 +0000 (12:54 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Sat, 23 Jun 2007 11:54:02 +0000 (12:54 +0100)
This is an attempt to cut down on the number PC92Cs that are flying
around. It does this be storing the last PC92C and only sending
it (which should be ignored by other people if broadcast) and
a PC92A. It does mean that the PC92C could be quite out of date
but a fresher will be along soon(ish)

I have also increase the pc92 update time to one hour and
randomised it to one hour - upto 1/4 of the update time.

It will also do each node separately, rather than all together in
one big gob.

perl/DXChannel.pm
perl/DXProt.pm
perl/DXProtHandle.pm
perl/Route/Node.pm
perl/Version.pm

index 8ab5a6fbc7e4695974050d5e87d1fb3909ed22be..62773ab3312b7e1a488293eadf3d72aa97328603 100644 (file)
@@ -121,6 +121,7 @@ $count = 0;
                  handle_xml => '9,Handles XML,yesno',
                  do_pc9x => '9,Handles PC9x,yesno',
                  inqueue => '9,Input Queue,parray',
+                 next_pc92_update => '9,Next PC92 Update,atime',
                 );
 
 # object destruction
index 62d56e4810bf035128854a1f782d2d41845b699a..2130e3c37a73579b74ae988fd04364bfc495989e 100644 (file)
@@ -43,7 +43,7 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim
                        $investigation_int $pc19_version $myprot_version
                        %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck
                        $allowzero $decode_dk0wcy $send_opernam @checklist
-                       $eph_pc15_restime $pc92_update_period $last_pc92_update
+                       $eph_pc15_restime $pc92_update_period $pc92_obs_timeout
                        %pc92_find $pc92_find_timeout
                   );
 
@@ -73,10 +73,10 @@ $chatdupeage = 20 * 60 * 60;
 $chatimportfn = "$main::root/chat_import";
 $investigation_int = 12*60*60; # time between checks to see if we can see this node
 $pc19_version = 5466;                  # the visible version no for outgoing PC19s generated from pc59
-$pc92_update_period = 30*60;   # the period between PC92 C updates
-$last_pc92_update = time + int rand(180);              # the last time a PC92 config update
+$pc92_update_period = 60*60;   # the period between PC92 C updates
 %pc92_find = ();                               # outstanding pc92 find operations
 $pc92_find_timeout = 30;               # maximum time to wait for a reply
+$pc92_obs_timeout = $pc92_update_period; # the time between obscount countdowns
 
 
 
@@ -203,6 +203,12 @@ sub check
        return 0;
 }
 
+sub update_pc92_next
+{
+       my $self = shift;
+       $self->{next_pc92_update} = $main::systime + $pc92_update_period - int rand($pc92_update_period / 4);
+}
+
 sub init
 {
        do "$main::data/hop_table.pl" if -e "$main::data/hop_table.pl";
@@ -223,6 +229,7 @@ sub init
        $main::me->{version} = $main::version;
        $main::me->{build} = "$main::subversion.$main::build";
        $main::me->{do_pc9x} = 1;
+       $main::me->update_pc92_next;
 }
 
 #
@@ -330,6 +337,9 @@ sub start
        # run a script send the output to the debug file
        my $script = new Script(lc $call) || new Script('node_default');
        $script->run($self) if $script;
+
+       # set next_pc92_update time
+       $self->update_pc92_next;
 }
 
 #
@@ -436,6 +446,12 @@ sub process
                                $dxchan->{lastping} += $dxchan->{pingint} / 2 unless @{$dxchan->{pingtime}};
                        }
                }
+
+               # send out a PC92 config record if required
+               if ($main::systime >= $dxchan->{next_pc92_update}) {
+                       $dxchan->send_pc92_config;
+                       $dxchan->update_pc92_next;
+               }
        }
 
        Investigate::process();
@@ -448,11 +464,9 @@ sub process
                eph_clean();
                import_chat();
 
-               if ($main::systime >= $last_pc92_update + $pc92_update_period) {
-                       dbg("ROUTE: sending pc92 update") if isdbg('route');
-                       send_pc92_update();
+               if ($main::systime >= $pc92_obs_timeout) {
                        time_out_pc92_routes();
-                       $last_pc92_update = $main::systime + int rand(5*60);
+                       $pc92_obs_timeout = $main::systime + $pc92_update_period;
                }
 
                $last10 = $t;
@@ -747,42 +761,44 @@ sub send_local_config
        dbg('DXProt::send_local_config') if isdbg('trace');
 
        # send our nodes
-       if ($self->{do_pc9x}) {
-               $self->send_pc92_config;
+       my $node;
+       my @nodes;
+       my @localnodes;
+       my @remotenodes;
+
+       if ($self->{isolate}) {
+               @localnodes = ( $main::routeroot );
+               $self->send_route($main::mycall, \&pc19, 1, $main::routeroot);
+       } elsif ($self->{do_pc9x}) {
+               my $node = Route::Node::get($self->{call});
+               $self->send_last_pc92_config($main::routeroot);
+               $self->send(pc92a($main::routeroot, $node)) unless $main::routeroot->last_PC92C =~ /$self->{call}/;
        } else {
-               my $node;
-               my @nodes;
-               my @localnodes;
-               my @remotenodes;
+               # create a list of all the nodes that are not connected to this connection
+               # and are not themselves isolated, this to make sure that isolated nodes
+               # don't appear outside of this node
 
-               if ($self->{isolate}) {
-                       @localnodes = ( $main::routeroot );
-                       $self->send_route($main::mycall, \&pc19, 1, $main::routeroot);
-               } else {
-                       # create a list of all the nodes that are not connected to this connection
-                       # and are not themselves isolated, this to make sure that isolated nodes
-                       # don't appear outside of this node
-
-                       # send locally connected nodes
-                       my @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} } DXChannel::get_all_nodes();
-                       @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan if @dxchan;
-                       $self->send_route($main::mycall, \&pc19, scalar(@localnodes)+1, $main::routeroot, @localnodes);
-
-                       my $node;
-                       my @rawintcalls = map { $_->nodes } @localnodes if @localnodes;
-                       my @intcalls;
-                       for $node (@rawintcalls) {
-                               push @intcalls, $node unless grep $node eq $_, @intcalls;
-                       }
-                       my $ref = Route::Node::get($self->{call});
-                       my @rnodes = $ref->nodes;
-                       for $node (@intcalls) {
-                               push @remotenodes, Route::Node::get($node) unless grep $node eq $_, @rnodes, @remotenodes;
-                       }
-                       $self->send_route($main::mycall, \&pc19, scalar(@remotenodes), @remotenodes);
+               # send locally connected nodes
+               my @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} } DXChannel::get_all_nodes();
+               @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan if @dxchan;
+               $self->send_route($main::mycall, \&pc19, scalar(@localnodes)+1, $main::routeroot, @localnodes);
+
+               my $node;
+               my @rawintcalls = map { $_->nodes } @localnodes if @localnodes;
+               my @intcalls;
+               for $node (@rawintcalls) {
+                       push @intcalls, $node unless grep $node eq $_, @intcalls;
+               }
+               my $ref = Route::Node::get($self->{call});
+               my @rnodes = $ref->nodes;
+               for $node (@intcalls) {
+                       push @remotenodes, Route::Node::get($node) unless grep $node eq $_, @rnodes, @remotenodes;
                }
+               $self->send_route($main::mycall, \&pc19, scalar(@remotenodes), @remotenodes);
+       }
 
-               # get all the users connected on the above nodes and send them out
+       # get all the users connected on the above nodes and send them out
+       unless ($self->{do_pc9x}) {
                foreach $node ($main::routeroot, @localnodes, @remotenodes) {
                        if ($node) {
                                my @rout = map {my $r = Route::User::get($_); $r ? ($r) : ()} $node->users;
@@ -824,50 +840,58 @@ sub gen_pc92_update
        # send 'my' configuration for all channels
        push @lines, gen_my_pc92_config($main::routeroot);
 
-       if ($with_pc92_nodes) {
+#      if ($with_pc92_nodes) {
                # send out the configuration of all the directly connected PC92 nodes with current configuration
                # but with the dates that the last config came in with.
-               @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} && $_->{do_pc9x} } DXChannel::get_all_nodes();
-               dbg("ROUTE: pc92 dxchan: " . join(',', map{$_->{call}} @dxchan)) if isdbg('routelow');
-               @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan;
-               dbg("ROUTE: pc92 localnodes: " . join(',', map{$_->{call}} @localnodes)) if isdbg('routelow');
-               foreach $node (@localnodes) {
-                       if ($node && $node->lastid->{92}) {
-                               my @rout = map {my $r = Route::get($_); $r ? ($r) : ()} $node->nodes, $node->users;
-                               push @lines, gen_pc92_with_time($node->call, 'C', $node->lastid->{92}, @rout);
-                       }
-               }
-       }
+#              @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} && $_->{do_pc9x} } DXChannel::get_all_nodes();
+#              dbg("ROUTE: pc92 dxchan: " . join(',', map{$_->{call}} @dxchan)) if isdbg('routelow');
+#              @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan;
+#              dbg("ROUTE: pc92 localnodes: " . join(',', map{$_->{call}} @localnodes)) if isdbg('routelow');
+#              foreach $node (@localnodes) {
+#                      if ($node && $node->lastid->{92}) {
+#                              my @rout = map {my $r = Route::get($_); $r ? ($r) : ()} $node->nodes, $node->users;
+#                              push @lines, gen_pc92_with_time($node->call, 'C', $node->lastid->{92}, @rout);
+#                      }
+#              }
+#      }
 
        # send the configuration of all the directly connected 'external' nodes that don't handle PC92
        # out with the 'external' marker on the first node.
-       @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} && !$_->{do_pc9x} } DXChannel::get_all_nodes();
-       dbg("ROUTE: non pc92 dxchan: " . join(',', map{$_->{call}} @dxchan)) if isdbg('routelow');
-       @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan;
-       dbg("ROUTE: non pc92 localnodes: " . join(',', map{$_->{call}} @localnodes)) if isdbg('routelow');
-       foreach $node (@localnodes) {
-               if ($node) {
-                       push @lines, gen_my_pc92_config($node);
-               }
-       }
+#      @dxchan = grep { $_->call ne $main::mycall && $_ != $self && !$_->{isolate} && !$_->{do_pc9x} } DXChannel::get_all_nodes();
+#      dbg("ROUTE: non pc92 dxchan: " . join(',', map{$_->{call}} @dxchan)) if isdbg('routelow');
+#      @localnodes = map { my $r = Route::Node::get($_->{call}); $r ? $r : () } @dxchan;
+#      dbg("ROUTE: non pc92 localnodes: " . join(',', map{$_->{call}} @localnodes)) if isdbg('routelow');
+#      foreach $node (@localnodes) {
+#              if ($node) {
+#                      push @lines, gen_my_pc92_config($node);
+#              }
+#      }
 
        dbg('ROUTE: DXProt::gen_pc92_update end with ' . scalar @lines . ' lines') if isdbg('routelow');
        return @lines;
 }
 
 
+sub send_last_pc92_config
+{
+       my $self = shift;
+       my $node = shift;
+       if (my $l = $node->last_PC92C) {
+               $self->send($l);
+       } else {
+               $self->send_pc92_config($node);
+       }
+}
+
 sub send_pc92_config
 {
        my $self = shift;
+       my $node = shift;
 
        dbg('DXProt::send_pc92_config') if isdbg('trace');
 
-       my @out = $self->gen_pc92_update(1);
-
-       # send the complete config out on this interface
-       for (@out) {
-               $self->send($_);
-       }
+       $node->last_PC92C(gen_my_pc92_config($node));
+       $self->send($node->last_PC92C);
 }
 
 sub send_pc92_update
@@ -1202,7 +1226,7 @@ sub send_route
                                if ($filter) {
                                        push @rin, $r;
                                } else {
-                                       dbg("DXPROT: $self->{call}/" . $r->call . " rejected by output filter") if isdbg('chanerr');
+                                       dbg("PCPROT: $self->{call}/" . $r->call . " rejected by output filter") if isdbg('filter');
                                }
                        } else {
                                dbg("was sent a null value") if isdbg('chanerr');
index 0010ab4504ce171983d2d7cf40311d85044608af..d739d65d72a8cef9c4ac401145f619a4fe12230f 100644 (file)
@@ -96,7 +96,7 @@ sub handle_10
        # if we are converting announces to talk is it a dup?
        if ($ann_to_talk) {
                if (AnnTalk::is_talk_candidate($from, $_[3]) && AnnTalk::dup($from, $to, $_[3])) {
-                       dbg("DXPROT: Dupe talk from announce, dropped") if isdbg('chanerr');
+                       dbg("PCPROT: Dupe talk from announce, dropped") if isdbg('chanerr');
                        return;
                }
        }
@@ -595,12 +595,16 @@ sub handle_18
        my $origin = shift;
        $self->state('init');
 
+       my $parent = Route::Node::get($self->{call});
+
        # record the type and version offered
        if ($_[1] =~ /DXSpider Version: (\d+\.\d+) Build: (\d+(?:\.\d+)?)/) {
-               $self->version(53 + $1);
+               $self->{version} = 53 + $1;
                $self->user->version(53 + $1);
-               $self->build(0 + $2);
+               $parent->version(0 + $1);
+               $self->{build} = 0 + $2;
                $self->user->build(0 + $2);
+               $parent->build(0 + $2);
                unless ($self->is_spider) {
                        $self->user->sort('S');
                        $self->user->put;
@@ -618,7 +622,6 @@ sub handle_18
        }
 
        # first clear out any nodes on this dxchannel
-       my $parent = Route::Node::get($self->{call});
        my @rout = $parent->del_nodes;
        $self->route_pc21($origin, $line, @rout, $parent) if @rout;
        $self->send_local_config();
@@ -659,7 +662,7 @@ sub handle_19
        # first get the INTERFACE node
        my $parent = Route::Node::get($self->{call});
        unless ($parent) {
-               dbg("DXPROT: my parent $self->{call} has disappeared");
+               dbg("PCPROT: my parent $self->{call} has disappeared");
                $self->disconnect;
                return;
        }
@@ -775,21 +778,6 @@ sub handle_19
        }
 }
 
-sub send_delayed_pc92
-{
-       my $self = shift;
-
-       # send out new PC92 config to everyone else
-       my $line = gen_my_pc92_config($main::me);
-       $self->broadcast_route_pc9x($main::mycall, undef, $line, 0);
-
-       # if this is an external node then send out the external config
-       unless ($self->{do_pc9x}) {
-               $line = gen_my_pc92_config(Route::Node::get($self->{call}));
-               $self->broadcast_route_pc9x($main::mycall, undef, $line, 0);
-       }
-}
-
 # send local configuration
 sub handle_20
 {
@@ -804,11 +792,11 @@ sub handle_20
                $self->disconnect;
                return;
        }
-       $self->send_local_config();
+       $self->send_local_config;
        $self->send(pc22());
        $self->state('normal');
        $self->{lastping} = 0;
-       $self->send_delayed_pc92;
+       $self->route_pc92a($main::mycall, $line, $main::routeroot, Route::Node::get($self->{call}));
 }
 
 # delete a cluster from the list
@@ -898,7 +886,7 @@ sub handle_22
        }
        $self->{lastping} = 0;
        $self->state('normal');
-       $self->send_delayed_pc92;
+       $self->route_pc92a($main::mycall, undef, $main::routeroot, Route::Node::get($self->{call}));
 }
 
 # WWV info
@@ -1462,13 +1450,13 @@ sub check_pc9x_t
                if ($parent->call ne $main::mycall) {
                        my $lastid = $parent->lastid->{$pc} || 0;
                        if ($t < $lastid) {
-                               if (my $d = $lastid-86400+$t > $pc9x_past_age) {
-                                       dbg("PCPROT: $call id $t <= $lastid, ignored") if isdbg('chanerr');
+                               if ($lastid-86400+$t > $pc9x_past_age) {
+                                       dbg("PCPROT: dup id on $t <= $lastid (midnight rollover), ignored") if isdbg('chanerr');
                                        return;
                                }
                        }
                        if ($lastid >= $t) {
-                               dbg("PCPROT: dup id on $call = $lastid, ignored") if isdbg('chanerr');
+                               dbg("PCPROT: dup id on $call $lastid >= $t, ignored") if isdbg('chanerr');
                                return;
                        }
                }
@@ -1574,7 +1562,7 @@ sub handle_92
                        my ($call, $is_node, $is_extnode, $here, $version, $build) = @{$ent[0]};
                        if ($call && $is_node) {
                                if ($call eq $main::mycall) {
-                                       dbg("PCPROT: looped back on node entry, ignored") if isdbg('chanerr');
+                                       dbg("PCPROT: $call looped back onto $main::mycall, ignored") if isdbg('chanerr');
                                        return;
                                }
                                if ($is_extnode) {
@@ -1642,7 +1630,7 @@ sub handle_92
                                                push @users, $r->[0];
                                        }
                                } else {
-                                       dbg("DXPROT: pc92 call entry '$_' not decoded, ignored") if isdbg('chanerr');
+                                       dbg("PCPROT: pc92 call entry '$_' not decoded, ignored") if isdbg('chanerr');
                                }
                        }
 
index e17b01f8858feaf4aee5f965c71bb6bf79fbf48a..581c570f36861a34031d6473cba3a55fee620415 100644 (file)
@@ -24,12 +24,14 @@ use vars qw(%list %valid @ISA $max $filterdef $obscount);
                  users => '0,Users,parray',
                  usercount => '0,User Count',
                  version => '0,Version',
+                 build => '0,Build',
                  handle_xml => '0,Using XML,yesno',
                  lastmsg => '0,Last Route Msg,atime',
                  lastid => '0,Last Route MsgID',
                  do_pc9x => '0,Uses pc9x,yesno',
                  via_pc92 => '0,Came in via pc92,yesno',
                  obscount => '0,Obscount',
+                 last_PC92C => '9,Last PC92C',
 );
 
 $filterdef = $Route::filterdef;
index b63bf77fa0e25b0abc5165b14406992ae73662e9..237f919c674614530092a15e87fac79864f42bca 100644 (file)
@@ -11,6 +11,6 @@ use vars qw($version $subversion $build);
 
 $version = '1.54';
 $subversion = '0';
-$build = '64';
+$build = '65';
 
 1;