allow PC92(A/D) to be slugged and aggregated
authorDirk Koopman <djk@tobit.co.uk>
Wed, 12 Sep 2007 19:43:28 +0000 (20:43 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Wed, 12 Sep 2007 19:43:28 +0000 (20:43 +0100)
Wait for a period of time before issuing pc92a or d records
and then aggregate them together as a collection of adds or deletes
in just (up to) two sentences, instead of one per event.

This has the side effect of (nearly) eliminating the "login, fire a
spot, logoff" merchants.

perl/DXCommandmode.pm
perl/DXProt.pm
perl/DXProtHandle.pm
perl/Version.pm

index 47b68667ca6e9d570589a3e0960b6c02cf12d82c..691e29b2d6b3fa928933a878ec07221b579957da 100644 (file)
@@ -65,13 +65,14 @@ sub new
        # routing, this must go out here to prevent race condx
        my $pkg = shift;
        my $call = shift;
-       my @rout = $main::routeroot->add_user($call, Route::here(1));
+#      my @rout = $main::routeroot->add_user($call, Route::here(1));
+       DXProt::_add_thingy($main::routeroot, [$call, 0, 0, 1]);
 
        # ALWAYS output the user
        my $ref = Route::User::get($call);
        if ($ref) {
                $main::me->route_pc16($main::mycall, undef, $main::routeroot, $ref);
-               $main::me->route_pc92a($main::mycall, undef, $main::routeroot, $ref);
+               $main::me->route_pc92a($main::mycall, undef, $main::routeroot, $ref) unless $DXProt::pc92_slug_changes;
        }
 
        return $self;
@@ -606,12 +607,14 @@ sub disconnect
        my $uref = Route::User::get($call);
        my @rout;
        if ($uref) {
-               @rout = $main::routeroot->del_user($uref);
+#              @rout = $main::routeroot->del_user($uref);
+               @rout = DXProt::_del_thingy($main::routeroot, [$call, 0]);
+
                dbg("B/C PC17 on $main::mycall for: $call") if isdbg('route');
 
                # issue a pc17 to everybody interested
                $main::me->route_pc17($main::mycall, undef, $main::routeroot, $uref);
-               $main::me->route_pc92d($main::mycall, undef, $main::routeroot, $uref);
+               $main::me->route_pc92d($main::mycall, undef, $main::routeroot, $uref) unless $DXProt::pc92_slug_changes;
        } else {
                confess "trying to disconnect a non existant user $call";
        }
index 42479d86216ff9a43df0d773f77be59bbe417ebc..e6f04a7f0a0113162d3f7c53f2079197a28e8131 100644 (file)
@@ -45,7 +45,7 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim
                        $allowzero $decode_dk0wcy $send_opernam @checklist
                        $eph_pc15_restime $pc92_update_period $pc92_obs_timeout
                        %pc92_find $pc92_find_timeout $pc92_short_update_period
-                       $next_pc92_obs_timeout
+                       $next_pc92_obs_timeout $pc92_slug_changes $last_pc92_slug
                   );
 
 $pc11_max_age = 1*3600;                        # the maximum age for an incoming 'real-time' pc11
@@ -82,7 +82,6 @@ $pc92_obs_timeout = 60*60; # the time between obscount for incoming countdowns
 $next_pc92_obs_timeout = $main::systime + 60*60; # the time between obscount countdowns
 
 
-
 @checklist =
 (
  [ qw(i c c m bp bc c) ],                      # pc10
@@ -481,9 +480,17 @@ sub process
                                dbg("ROUTE: pc92 broadcast candidate: $dxchan->{call}") if isdbg('obscount');
                                if ($dxchan == $main::me || !$dxchan->{do_pc9x}) {
                                        $dxchan->broadcast_pc92_update($dxchan->{call});
+                                       $last_pc92_slug = 0 if $dxchan == $main::me;
                                }
                        }
                }
+
+               if ($pc92_slug_changes && $main::systime >= $last_pc92_slug + $pc92_slug_changes) {
+                       my ($add, $del) = gen_pc92_changes();
+                       $main::me->route_pc92d($main::mycall, undef, $main::routeroot, @$del) if @$del;
+                       $main::me->route_pc92a($main::mycall, undef, $main::routeroot, @$add) if @$add;
+                       clear_pc92_changes();
+               }
        }
 
        if ($main::systime - 3600 > $last_hour) {
@@ -866,6 +873,7 @@ sub gen_my_pc92_config
        my $node = shift;
 
        if ($node->{call} eq $main::mycall) {
+               clear_pc92_changes();           # remove any slugged data, we are generating it as now
                my @dxchan = grep { $_->call ne $main::mycall && !$_->{isolate} } DXChannel::get_all();
                dbg("ROUTE: all dxchan: " . join(',', map{$_->{call}} @dxchan)) if isdbg('routelow');
                my @localnodes = map { my $r = Route::get($_->{call}); $r ? $r : () } @dxchan;
index 9e0f5ec4adb111ccf81f159a6368049cce558926..1b3506150d16c7be19ddb9ddfd19f29a0fba3ab5 100644 (file)
@@ -44,14 +44,15 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim
                        %nodehops $baddx $badspotter $badnode $censorpc
                        $allowzero $decode_dk0wcy $send_opernam @checklist
                        $eph_pc15_restime $pc9x_past_age $pc9x_future_age
-                       $pc10_dupe_age
+                       $pc10_dupe_age $pc92_slug_changes $last_pc92_slug
                   );
 
 $pc9x_past_age = 62*60;                        # maximum age in the past of a px9x (a config record might be the only
                                                                # thing a node might send - once an hour)
 $pc9x_future_age = 5*60;               # maximum age in the future ditto
 $pc10_dupe_age = 45;                   # just something to catch duplicate PC10->PC93 conversions
-
+$pc92_slug_changes = 0;                        # slug any changes going outward for this long
+$last_pc92_slug = 0;                   # the last time we sent out any delayed add or del PC92s
 
 # incoming talk commands
 sub handle_10
@@ -766,7 +767,7 @@ sub handle_19
 #              $self->route_pc21($self->{call}, $line, @rout);
                $self->route_pc19($self->{call}, $line, @rout);
        }
-       if (@pc92out) {
+       if (@pc92out && !$pc92_slug_changes) {
                $self->route_pc92a($main::mycall, $line, $main::routeroot, @pc92out) if $self->{state} eq 'normal';
        }
 }
@@ -1364,6 +1365,9 @@ sub _encode_pc92_call
        return "$flag$call$extra";
 }
 
+my %things_add;
+my %things_del;
+
 sub _add_thingy
 {
        my $parent = shift;
@@ -1379,6 +1383,10 @@ sub _add_thingy
                        dbg("ROUTE: added user $call to " . $parent->call) if isdbg('routelow');
                        @rout = $parent->add_user($call, Route::here($here));
                }
+               if ($pc92_slug_changes && $parent == $main::routeroot) {
+                       $things_add{$call} = Route::get($call);
+                       delete $things_del{$call};
+               }
        }
        return @rout;
 }
@@ -1390,19 +1398,40 @@ sub _del_thingy
        my ($call, $is_node, $is_extnode, $here, $version, $build) = @$s;
        my @rout;
        if ($call) {
+               my $ref;
                if ($is_node) {
-                       my $nref = Route::Node::get($call);
+                       $ref = Route::Node::get($call);
                        dbg("ROUTE: deleting node $call from " . $parent->call) if isdbg('routelow');
-                       @rout = $nref->del($parent) if $nref;
+                       @rout = $ref->del($parent) if $ref;
                } else {
-                       my $uref = Route::User::get($call);
+                       $ref = Route::User::get($call);
                        dbg("ROUTE: deleting user $call from " . $parent->call) if isdbg('routelow');
-                       @rout = $parent->del_user($uref) if $uref;
+                       @rout = $parent->del_user($ref) if $ref;
+               }
+               if ($pc92_slug_changes && $parent == $main::routeroot) {
+                       $things_del{$call} = $ref unless exists $things_add{$call};
+                       delete $things_add{$call};
                }
        }
        return @rout;
 }
 
+# this will only happen if we are slugging changes and
+# there are some changes to be sent, it will create an add or a delete
+# or both
+sub gen_pc92_changes
+{
+       my @add = values %things_add;
+       my @del = values %things_del;
+       return (\@add, \@del);
+}
+
+sub clear_pc92_changes
+{
+       %things_add = %things_del = ();
+       $last_pc92_slug = $main::systime;
+}
+
 my $_last_time;
 my $_last_occurs;
 
index 67b77d78285b11415d40106f7b14c6526f4e9d42..d72986dcc35ff0add3bd34ae9a51ba26a52cc7e9 100644 (file)
@@ -11,6 +11,6 @@ use vars qw($version $subversion $build);
 
 $version = '1.54';
 $subversion = '0';
-$build = '137';
+$build = '138';
 
 1;