From 11d4503c67235600af279b57b785e5657faaf63c Mon Sep 17 00:00:00 2001 From: Dirk Koopman Date: Wed, 12 Sep 2007 20:43:28 +0100 Subject: [PATCH] allow PC92(A/D) to be slugged and aggregated 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 | 11 +++++++---- perl/DXProt.pm | 12 ++++++++++-- perl/DXProtHandle.pm | 43 ++++++++++++++++++++++++++++++++++++------- perl/Version.pm | 2 +- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm index 47b68667..691e29b2 100644 --- a/perl/DXCommandmode.pm +++ b/perl/DXCommandmode.pm @@ -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"; } diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 42479d86..e6f04a7f 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -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; diff --git a/perl/DXProtHandle.pm b/perl/DXProtHandle.pm index 9e0f5ec4..1b350615 100644 --- a/perl/DXProtHandle.pm +++ b/perl/DXProtHandle.pm @@ -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; diff --git a/perl/Version.pm b/perl/Version.pm index 67b77d78..d72986dc 100644 --- a/perl/Version.pm +++ b/perl/Version.pm @@ -11,6 +11,6 @@ use vars qw($version $subversion $build); $version = '1.54'; $subversion = '0'; -$build = '137'; +$build = '138'; 1; -- 2.34.1