X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXCluster.pm;h=8338cccb5a511c3da8e0d1096a5679d6520424fe;hb=2b58ccdf81685a1167a43c38705a0d84b9d8d661;hp=2ddd2358648f28616c2c8f2f197bce61303e9d4a;hpb=7432cb12ce865030c8b0315a30764e0088a59102;p=spider.git diff --git a/perl/DXCluster.pm b/perl/DXCluster.pm index 2ddd2358..8338cccb 100644 --- a/perl/DXCluster.pm +++ b/perl/DXCluster.pm @@ -14,101 +14,191 @@ package DXCluster; -use Exporter; -@ISA = qw(Exporter); -use Carp; use DXDebug; +use DXUtil; use strict; use vars qw(%cluster %valid); -%cluster = (); # this is where we store the dxcluster database +%cluster = (); # this is where we store the dxcluster database %valid = ( - mynode => '0,Parent Node,showcall', - call => '0,Callsign', - confmode => '0,Conference Mode,yesno', - here => '0,Here?,yesno', - dxchan => '5,Channel ref', - pcversion => '5,Node Version', - list => '5,User List,dolist', - users => '0,No of Users', -); + mynode => '0,Parent Node', + call => '0,Callsign', + confmode => '0,Conference Mode,yesno', + here => '0,Here?,yesno', + dxchancall => '5,Channel Call', + pcversion => '5,Node Version', + list => '5,User List,DXCluster::dolist', + users => '0,No of Users', + ); + +use vars qw($VERSION $BRANCH); +$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ ); +$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ ) || 0; +$main::build += $VERSION; +$main::branch += $BRANCH; sub alloc { - my ($pkg, $dxchan, $call, $confmode, $here) = @_; - die "$call is already alloced" if $cluster{$call}; - my $self = {}; - $self->{call} = $call; - $self->{confmode} = $confmode; - $self->{here} = $here; - $self->{dxchan} = $dxchan; + my ($pkg, $dxchan, $call, $confmode, $here) = @_; + die "$call is already alloced" if $cluster{$call}; + my $self = {}; + $self->{call} = $call; + $self->{confmode} = $confmode; + $self->{here} = $here; + $self->{dxchancall} = $dxchan->call; + + $cluster{$call} = bless $self, $pkg; + return $self; +} + +# get an entry exactly as it is +sub get_exact +{ + my ($pkg, $call) = @_; - $cluster{$call} = bless $self, $pkg; - return $self; + # belt and braces + $call = uc $call; + + # search for 'as is' only + return $cluster{$call}; } +# # search for a call in the cluster +# taking into account SSIDs +# sub get { - my ($pkg, $call) = @_; - return $cluster{$call}; + my ($pkg, $call) = @_; + + # belt and braces + $call = uc $call; + + # search for 'as is' + my $ref = $cluster{$call}; + return $ref if $ref; + + # search for the unSSIDed one + $call =~ s/-\d+$//o; + $ref = $cluster{$call}; + return $ref if $ref; + + # search for the SSIDed one + my $i; + for ($i = 1; $i < 17; $i++) { + $ref = $cluster{"$call-$i"}; + return $ref if $ref; + } + return undef; } # get all sub get_all { - return values(%cluster); + return values(%cluster); } # return a prompt for a field sub field_prompt { - my ($self, $ele) = @_; - return $valid{$ele}; + my ($self, $ele) = @_; + return $valid{$ele}; +} +# +# return a list of valid elements +# + +sub fields +{ + return keys(%valid); } # this expects a reference to a list in a node NOT a ref to a node sub dolist { - my $self = shift; - my $out; - my $ref; + my $self = shift; + my $out; + my $ref; - foreach $ref (@{$self}) { - my $s = $ref->{call}; - $s = "($s)" if !$ref->{here}; - $out .= "$s "; - } - chop $out; - return $out; + foreach my $call (keys %{$self}) { + $ref = $$self{$call}; + my $s = $ref->{call}; + $s = "($s)" if !$ref->{here}; + $out .= "$s "; + } + chop $out; + return $out; } # this expects a reference to a node sub showcall { - my $self = shift; - return $self->{call}; + my $self = shift; + return $self->{call}; } -sub DESTROY +# the answer required by show/cluster +sub cluster +{ + my $users = DXCommandmode::get_all(); + my $uptime = main::uptime(); + my $tot = $DXNode::users; + + return " $DXNode::nodes nodes, $users local / $tot total users Max users $DXNode::maxusers Uptime $uptime"; +} + +sub mynode { - my $self = shift; - dbg('cluster', "destroying $self->{call}\n"); + my $self = shift; + my $noderef = shift; + + if ($noderef) { + $self->{mynode} = $noderef->call; + } else { + $noderef = DXCluster->get_exact($self->{mynode}); + unless ($noderef) { + my $mynode = $self->{mynode}; + my $call = $self->{call}; + dbg("parent node $mynode has disappeared from $call") if isdbg('err'); + } + } + return $noderef; +} + +sub dxchan +{ + my $self = shift; + my $dxchan = shift; + + if ($dxchan) { + $self->{dxchancall} = $dxchan->call; + } else { + $dxchan = DXChannel->get($self->{dxchancall}); + unless ($dxchan) { + my $dxcall = $self->{dxchancall}; + my $call = $self->{call}; + dbg("parent dxchan $dxcall has disappeared from $call") if isdbg('err'); + } + } + return $dxchan; } no strict; sub AUTOLOAD { - my $self = shift; - my $name = $AUTOLOAD; + my $self = shift; + my $name = $AUTOLOAD; - return if $name =~ /::DESTROY$/; - $name =~ s/.*:://o; + return if $name =~ /::DESTROY$/; + $name =~ s/.*:://o; - confess "Non-existant field '$AUTOLOAD'" if !$valid{$name}; - @_ ? $self->{$name} = shift : $self->{$name} ; + confess "Non-existant field '$AUTOLOAD'" if !$valid{$name}; + # this clever line of code creates a subroutine which takes over from autoload + # from OO Perl - Conway + *{$AUTOLOAD} = sub {@_ > 1 ? $_[0]->{$name} = $_[1] : $_[0]->{$name}} ; + @_ ? $self->{$name} = shift : $self->{$name} ; } # @@ -122,37 +212,33 @@ package DXNodeuser; use DXDebug; use strict; -my $users = 0; sub new { - my ($pkg, $dxchan, $node, $call, $confmode, $here) = @_; + my ($pkg, $dxchan, $node, $call, $confmode, $here) = @_; - die "tried to add $call when it already exists" if DXCluster->get($call); + die "tried to add $call when it already exists" if DXCluster->get_exact($call); - my $self = $pkg->alloc($dxchan, $call, $confmode, $here); - $self->{mynode} = $node; - $node->{list}->{$call} = $self; # add this user to the list on this node - $users++; - dbg('cluster', "allocating user $call to $node->{call} in cluster\n"); - return $self; + my $self = $pkg->alloc($dxchan, $call, $confmode, $here); + $self->{mynode} = $node->call; + $node->add_user($call, $self); + dbg("allocating user $call to $node->{call} in cluster\n") if isdbg('cluster'); + return $self; } sub del { - my $self = shift; - my $call = $self->{call}; - my $node = $self->{mynode}; - - delete $node->{list}->{$call}; - delete $DXCluster::cluster{$call}; # remove me from the cluster table - dbg('cluster', "deleting user $call from $node->{call} in cluster\n"); - $users-- if $users > 0; + my $self = shift; + my $call = $self->{call}; + my $node = $self->mynode; + + $node->del_user($call); + dbg("deleting user $call from $node->{call} in cluster\n") if isdbg('cluster'); } sub count { - return $users; # + 1 for ME (naf eh!) + return $DXNode::users; # + 1 for ME (naf eh!) } no strict; @@ -168,62 +254,108 @@ package DXNode; use DXDebug; use strict; -my $nodes = 0; +use vars qw($nodes $users $maxusers); + +$nodes = 0; +$users = 0; +$maxusers = 0; + sub new { - my ($pkg, $dxchan, $call, $confmode, $here, $pcversion) = @_; - my $self = $pkg->alloc($dxchan, $call, $confmode, $here); - $self->{version} = $pcversion; - $self->{list} = { } ; - $nodes++; - dbg('cluster', "allocating node $call to cluster\n"); - return $self; + my ($pkg, $dxchan, $call, $confmode, $here, $pcversion) = @_; + my $self = $pkg->alloc($dxchan, $call, $confmode, $here); + $self->{pcversion} = $pcversion; + $self->{list} = { } ; + $self->{mynode} = $self->call; # for sh/station + $self->{users} = 0; + $nodes++; + dbg("allocating node $call to cluster\n") if isdbg('cluster'); + return $self; } # get all the nodes sub get_all { - my $list; - my @out; - foreach $list (values(%DXCluster::cluster)) { - push @out, $list if $list->{pcversion}; - } - return @out; + my $list; + my @out; + foreach $list (values(%DXCluster::cluster)) { + push @out, $list if $list->{pcversion}; + } + return @out; } sub del { - my $self = shift; - my $call = $self->{call}; - my $ref; + my $self = shift; + my $call = $self->{call}; + my $ref; + + # delete all the listed calls + foreach $ref (values %{$self->{list}}) { + $ref->del(); # this also takes them out of this list + } + delete $DXCluster::cluster{$call}; # remove me from the cluster table + dbg("deleting node $call from cluster\n") if isdbg('cluster'); + $users -= $self->{users}; # it may be PC50 updated only therefore > 0 + $users = 0 if $users < 0; + $nodes--; + $nodes = 0 if $nodes < 0; +} - # delete all the listed calls - foreach $ref (values %{$self->{list}}) { - $ref->del(); # this also takes them out of this list - } - dbg('cluster', "deleting node $call from cluster\n"); - $nodes-- if $nodes > 0; +sub add_user +{ + my $self = shift; + my $call = shift; + my $ref = shift; + + $self->{list}->{$call} = $ref; # add this user to the list on this node + $self->{users} = keys %{$self->{list}}; + $users++; + $maxusers = $users+$nodes if $users+$nodes > $maxusers; +} + +sub del_user +{ + my $self = shift; + my $call = shift; + + delete $self->{list}->{$call}; + delete $DXCluster::cluster{$call}; # remove me from the cluster table + $self->{users} = keys %{$self->{list}}; + $users--; + $users = 0, warn "\$users gone neg, reset" if $users < 0; + $maxusers = $users+$nodes if $users+$nodes > $maxusers; } sub update_users { - my $self = shift; - if (%{$self->{list}}) { - $self->{users} = scalar %{$self->{list}}; - } else { - $self->{users} = shift; - } + my $self = shift; + my $count = shift; + $count = 0 unless $count; + + $users -= $self->{users}; + $self->{users} = $count unless keys %{$self->{list}}; + $users += $self->{users}; + $maxusers = $users+$nodes if $users+$nodes > $maxusers; } sub count { - return $nodes; # + 1 for ME! + return $nodes; # + 1 for ME! } sub dolist { } + +sub DESTROY +{ + my $self = shift; + undef $self->{list} if $self->{list}; +} + + 1; __END__