POE-Component-SNMP
view release on metacpan or search on metacpan
lib/POE/Component/SNMP/Dispatcher.pm view on Meta::CPAN
my ($this, $event) = @_;
return $this->_fileno_from_callback($event->[_CALLBACK]);
}
sub _fileno_from_callback {
my ($self, $callback) = @_;
# $callback->[1] is a $pdu object
return $callback->[1]->transport->fileno;
}
# }}} _get_fileno
# {{{ _alias
# this session runs as a singleton, here is its session alias:
sub _alias { '_poe_component_snmp_dispatcher' }
# }}} _alias
# }}} PRIVATE METHODS
# {{{ POE EVENTS
# By convention, all POE states, except _start and _stop, have
# two leading underscores.
# {{{ _start and _stop
sub _start {
$_[KERNEL]->alias_set(_alias())
}
sub _stop {
$_[KERNEL]->alias_remove(_alias());
undef $INSTANCE;
}
# }}} _start and _stop
# {{{ __dispatch_pdu
# We want to prevent conflicts between listening sockets and pending
# requests, because POE can't listen to two at a time on the same
# handle. If that socket is currently listening for a reply to a
# different request (eg $this->_current_pdu() is TRUE), the request is
# queued, otherwise it is dispatched immediately.
#
# (which again additionally POE-izes Net::SNMP)
#
# this event is invoked by _send_pdu()
sub __dispatch_pdu {
my ($this, @pdu_args) = @_[OBJECT, ARG0..$#_];
# these are the args this state was invoked with:
# @pdu_args = ( $pdu, $timeout, $retries );
my $pdu = $pdu_args[0];
my $fileno = $pdu->transport->fileno;
# enqueue or execute
if ($this->_current_pdu($fileno)) {
# this socket is busy. enqueue.
$this->_enqueue_pending_pdu($fileno => \@pdu_args);
DEBUG_INFO('queued request for [%d] %d requests pending',
$fileno, $this->_pending_pdu_count($fileno));
} else {
# this socket is free. execute.
DEBUG_INFO('sending request for [%d]', $fileno);
$this->_current_pdu($fileno => $pdu);
VERBOSE and DEBUG_INFO('{-------- SUPER::_send_pdu() for [%d]', $fileno);
$this->SUPER::_send_pdu(@pdu_args);
VERBOSE and DEBUG_INFO(' --------} SUPER::_send_pdu() for [%d]', $fileno );
}
}
# }}} __dispatch_pdu
# {{{ __schedule_event
# this event is invoked by schedule() / _event_insert()
sub __schedule_event {
my ($this, $event) = @_[ OBJECT, ARG0 ];
# $event->[_ACTIVE] is always true for us, and we ignore it.
#
# $event->[_TIME] is the epoch time this event should fire. We
# use that value for scheduling the POE event, then replace it
# with POE's alarm id.
#
# $event->[_CALLBACK] is an opaque callback reference.
#
# $event->[_DELAY] is how long from the time of scheduling to
# fire the event, in seconds
#
# We get this same $event back in cancel(), where we reference
# $event->[_TIME] as alarm id to deactivate.
if ($event->[_TIME] <= time) {
$this->_callback_execute($event->[_CALLBACK]); # no parameter cooking needed!
return;
}
my $timeout_id = $poe_kernel->alarm_set(__invoke_callback => $event->[_TIME], $event->[_CALLBACK]);
# stash the alarm id. since $event is a reference, this
# assignment is "global".
$event->[_TIME] = $timeout_id;
# I only use $event->[_DELAY] for debugging.
DEBUG_INFO("alarm id %d, %0.1f seconds [%d] %s",
$timeout_id, $event->[_DELAY],
$this->_get_fileno($event),
VERBOSE ? dump_args([ $event->[_CALLBACK] ]) : ''
);
}
# }}} __schedule_event
# {{{ __invoke_callback
( run in 1.820 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )