via RT wrote:
Show quoted text> <URL:
http://rt.cpan.org/Ticket/Display.html?id=21754 >
>
> On Wed Sep 27 17:52:14 2006, RDB wrote:
>> When closing the main window of my POE/Tk program, it terminates with:
>>
>> Can't locate object method "cancel" via package "Tk::After::Cancelled"
>> at /usr/lib/perl5/site_perl/5.8.8/POE/Loop/TkCommon.pm line 74.
>
> Does this happen with any Tk program, or one in particular? I'd like to
> narrow down a test case if possible.
I have one Tk program I use, loadavg_multi_snmp. I've attached it,
modified to only query localhost, community 'public'. It still
demonstrates the error. It requires PoCo::SNMP and Tk::Graph.
It consistently gives that exact message every time I close it. It
might perhaps be related to the fact that I have no "close this program"
Tk button/action, but just use the [X] button drawn by the OS, but
that's just a guess.
Hope this helps to narrow it down!
L8r,
Rob
#!/usr/bin/perl
use Tk;
use Tk::Graph;
use POE qw/Component::SNMP Component::Client::TCP/;
use Time::HiRes qw/time/;
use warnings;
use strict;
use constant SNMP_HOSTS => 1;
use constant STATUS_LINE => 1;
use constant SHOW_ALL_LOADS => 0;
my $VERBOSE = 0;
my $POLL_DELAY = $ENV{DELAY} || 5;
my $REDRAW_DELAY = 1;
$|++;
# {{{ SNMP variables
# snmpget -v1 -c public localhost 1.3.6.1.4.1.2021.10.1.3.1
# snmpget -v1 -c public localhost enterprises.ucdavis.laTable.laEntry.laLoad.1
#my $load1_oid = 'enterprises.ucdavis.laTable.laEntry.laLoad.1';
my $load1_oid = '.1.3.6.1.4.1.2021.10.1.3.1';
my $load5_oid = '.1.3.6.1.4.1.2021.10.1.3.2';
my $load15_oid = '.1.3.6.1.4.1.2021.10.1.3.3';
# hostname oid: system.sysName => 1.3.6.1.2.1.1.5.0
my $host_oid = '.1.3.6.1.2.1.1.5.0';
# }}} SNMP variables
# {{{ HOSTS
no warnings; # it wants to complain about the # chars in the qw// for
# the color values.
my %snmp_host =
(
localhost => [qw( localhost #FF0000 )], # red
);
my %snmp_community = ( );
# %snmp_host = ( ads => $snmp_host{ads} );
use warnings;
# }}} HOSTS
## STATES ##
# {{{ _start
sub _start {
my($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
my %config;
$kernel->alias_set('graph_window');
# {{{ snmp hosts
if (SNMP_HOSTS) {
while (my ($name, $etc) = each %snmp_host) {
my ($host, $one, $five, $fifteen) = @$etc;
my $name_01 = "${name}_01";
$config{$name_01} = {
-title => $name,
-color => $one,
};
## setup the snmp processes
POE::Component::SNMP->create(
hostname => $host,
community => $snmp_community{$host} || 'public',
alias => "snmp_$name",
# timeout => 4.8,
# timeout => $POLL_DELAY/2 - 0.5, # a little clearance
timeout => 1,
retries => 1,
localaddr => '64.146.132.121',
# debug => 0x3E,
# debug => 0x04, # transport
# debug => 0x08, # dispatcher
# debug => 0x0B, # dispatcher + transport
);
$heap->{snmp_hostnames}->{$host} = $name;
$heap->{fields}->{$name} = [ $name_01 ];
$kernel->call( "snmp_$name" => get => snmp_response =>
-varbindlist => [ $load1_oid ],
);
# mark poll time
$heap->{next}{$name} = $heap->{time}{$name} = time;
}
}
# }}} snmp hosts
# {{{ set up the graph widget
$heap->{ca} = $poe_main_window->Graph(
-type => 'LINE',
-linewidth => 2,
-look => 100,
-sortnames => 'alpha',
-legend => 1,
# -lineheight => 30,
# -threed => 5,
-headroom => 10,
# how is this supposed to work?
-balloon => 1,
# -printvalue => '%s %s',
# our data
-config => \%config,
);
$poe_main_window->configure(-title => "load averages");
$poe_main_window->iconbitmap('@/usr/share/xemacs/xemacs-packages/etc/frame-icon/radioactive.xbm');
$heap->{ca}->pack(
-expand => 1,
-fill => 'both',
);
$heap->{values} = []; # empty update list;
$kernel->call( $session => 'redraw_graph' );
# }}} set up the graph widget
# {{{ and the status line
if (STATUS_LINE) {
# Create a Status Line widget, and pass it to Client::TCP
my $st = $poe_main_window->Label(-text => "- reading stats -");
$st->pack(-side => 'bottom', -anchor => 'n', -fill => 'x');
$heap->{stat_watcher} =
POE::Component::Client::TCP->new( RemoteAddress => 'log1',
RemotePort => '1001',
Args => [ $st ],
Started => sub { $_[HEAP]{st} = $_[ARG0] },
ServerInput => \&got_status_line,
);
}
# }}} and the status line
}
# }}} _start
# {{{ snmp_response
sub snmp_response {
my($kernel, $heap, $request, $response) = @_[KERNEL, HEAP, ARG0, ARG1];
my ($alias, $host, $cmd, @args) = @$request;
my ($results) = @$response;
my $loadavg = 0;
my ($name) = $alias =~ /snmp_(.*)/;
if (ref $results) {
# GOOD ANSWER!
unless ($name) {
$host = $results->{$host_oid};
$name = $heap->{snmp_hostnames}{$host};
}
($loadavg) = @{$results}{ $load1_oid };
} else {
$VERBOSE and warn "SNMP $alias ($host): $results\n";
}
my $delay;
my $time = time;
my $next = $heap->{next}{$name};
if ($time < $next) {
$delay = $next - $time;
} else {
$delay = $POLL_DELAY - ($time - $next);
}
$heap->{time}{$name} = $next;
$heap->{next}{$name} = $next + $POLL_DELAY;
$kernel->post( "snmp_$name" => get => snmp_response =>
-varbindlist => [ $load1_oid ],
-delay => $delay,
);
my $fields = $heap->{fields}->{$name};
unless (defined $fields) {
warn "No such name $name";
}
# stash the incoming values on the heap, to be updated in
# redraw_graph()
push @{$heap->{values}}, ($fields->[0] => $loadavg);
}
# }}} snmp_response
# {{{ snmp_poll
sub snmp_poll {
my($kernel, $heap, $name, $host, $delay) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
$host ||= '';
my $now = int time;
my $when = $now - $now % 5 + 5; # next 5s tick
# poll an SNMP host
$kernel->alarm( "snmp_$name" => $when, get => snmp_response =>
-varbindlist => [ $load1_oid ],
);
}
# }}} snmp_poll
# {{{ got_status_line
# Input from my custom stat reporting service
sub got_status_line {
my($heap, $input) = @_[HEAP, ARG0];
my ($status) = $input =~ m/Load \S+ \| (.+?Day)/;
$heap->{st}->configure(-text => $status);
}
# }}} got_status_line
# {{{ redraw_graph
sub redraw_graph {
my ($kernel, $heap) = @_[KERNEL, HEAP];
# defer the call to $heap->{ca}->set() to be the *LAST* call in
# this function.
my %v = @{$heap->{values}};
$heap->{values} = []; # empty update list
$kernel->delay_add( redraw_graph => $REDRAW_DELAY );
return unless scalar keys %v; # don't redraw unless we have changed data
$heap->{ca}->set(\%v);
}
# }}} redraw_graph
POE::Session->create
( inline_states => {
_start => \&_start,
snmp_poll => \&snmp_poll,
snmp_response => \&snmp_response,
redraw_graph => \&redraw_graph,
}
);
POE::Kernel->run;