Permalink
Browse files

Refactor to use call_gate() more. Hoist signal parameters outside the…

… delivery loop, thanks to Matt Trout.
  • Loading branch information...
1 parent b9341c0 commit 67e618a1a7b87b5945179bcf0673a20d002c2c4d @rcaputo committed Aug 16, 2009
Showing with 167 additions and 242 deletions.
  1. +29 −12 docs/Delay.pm
  2. +34 −26 docs/Handle.pm
  3. +36 −42 docs/Signal.pm
  4. +6 −18 docs/SignalChild.pm
  5. +3 −0 docs/Stage.pm
  6. +31 −83 docs/StageRole.pm
  7. +3 −0 docs/UdpPeer.pm
  8. +3 −0 docs/UdpPeerRole.pm
  9. +12 −57 docs/Wheel.pm
  10. +3 −0 docs/WheelRun.pm
  11. +7 −4 docs/requirements.otl
View
@@ -2,14 +2,15 @@ package Delay;
use Moose;
extends qw(Stage);
+use Scalar::Util qw(weaken);
has interval => (
isa => 'Num',
is => 'rw',
);
has alarm_id => (
- isa => 'Str',
+ isa => 'Str|Undef',
is => 'rw',
);
@@ -26,12 +27,22 @@ sub BUILD {
sub repeat {
my $self = shift;
+ return unless defined $self->interval() and $self->call_gate("repeat");
+
+ # Stop a previous alarm?
+
+ $self->stop() if defined $self->alarm_id();
+
+ # Put a weak $self in an envelope that can be passed around.
+
+ my $envelope = [ $self ];
+ weaken $envelope->[0];
+
$self->alarm_id(
- $POE::Kernel::poe_kernel->call(
- $self->session_id(),
- 'timer_set',
+ $POE::Kernel::poe_kernel->delay_set(
+ 'timer_due',
$self->interval(),
- $self
+ $envelope,
)
);
}
@@ -45,13 +56,19 @@ sub _deliver {
sub DEMOLISH {
my $self = shift;
- if ($self->alarm_id()) {
- $POE::Kernel::poe_kernel->call(
- $self->session_id(),
- 'timer_clear',
- $self->alarm_id(),
- );
- }
+ $self->stop();
}
+sub stop {
+ my $self = shift;
+
+ return unless defined $self->alarm_id() and $self->call_gate("stop");
+
+ $POE::Kernel::poe_kernel->alarm_remove($self->alarm_id());
+ $self->alarm_id(undef);
+}
+
+no Moose;
+__PACKAGE__->meta()->make_immutable();
+
1;
View
@@ -4,6 +4,7 @@ package Handle;
use Moose;
extends 'Stage';
+use Scalar::Util qw(weaken);
has handle => (
isa => 'IO::Handle',
@@ -30,20 +31,36 @@ has ex => (
sub BUILD {
my $self = shift;
+ $self->start();
+}
+
+sub start {
+ my $self = shift;
+ return unless $self->call_gate("start");
+
+ my $envelope = [ $self ];
+ weaken $envelope->[0];
+
+ $POE::Kernel::poe_kernel->select_read(
+ $self->handle(), 'select_ready', $envelope, 'read'
+ ) if $self->rd();
+
+ $POE::Kernel::poe_kernel->select_write(
+ $self->handle(), 'select_ready', $envelope, 'write'
+ ) if $self->wr();
- my @selects;
- push @selects, [ 'read', $self->handle() ] if $self->rd();
- push @selects, [ 'write', $self->handle() ] if $self->wr();
- push @selects, [ 'expedite', $self->handle() ] if $self->ex();
-
- if (@selects) {
- $POE::Kernel::poe_kernel->call(
- $self->session_id(),
- 'select_on',
- $self,
- @selects
- );
- }
+ $POE::Kernel::poe_kernel->select_expedite(
+ $self->handle(), 'select_ready', $envelope, 'expedite'
+ ) if $self->ex();
+}
+
+sub stop {
+ my $self = shift;
+ return unless $self->call_gate("stop");
+
+ $POE::Kernel::poe_kernel->select_read($self->handle(), undef) if $self->rd();
+ $POE::Kernel::poe_kernel->select_write($self->handle(), undef) if $self->wr();
+ $POE::Kernel::poe_kernel->select_expedite($self->handle(), undef) if $self->ex();
}
sub _deliver {
@@ -58,19 +75,10 @@ sub _deliver {
sub DEMOLISH {
my $self = shift;
-
- my @selects;
- push @selects, [ 'read', $self->handle() ] if $self->rd();
- push @selects, [ 'write', $self->handle() ] if $self->wr();
- push @selects, [ 'expedite', $self->handle() ] if $self->ex();
-
- if (@selects) {
- $POE::Kernel::poe_kernel->call(
- $self->session_id(),
- 'select_off',
- @selects
- );
- }
+ $self->stop();
}
+no Moose;
+__PACKAGE__->meta()->make_immutable();
+
1;
View
@@ -8,15 +8,17 @@ use Scalar::Util qw(weaken);
# So we must map each distinct signal to all the interested objects.
my %session_watchers;
+my %signal_param_names;
has name => (
isa => 'Str|Undef',
is => 'rw',
default => 'TERM',
);
-sub event_param_names {
- return [ ];
+sub _register_signal_params {
+ my ($class, @names) = @_;
+ $signal_param_names{$class->meta->get_attribute("name")->default()} = \@names;
}
sub BUILD {
@@ -36,44 +38,15 @@ sub BUILD {
}
}
-sub DESTROY {
- my $self = shift;
-
- my $sw = $session_watchers{$self->name()}->{$self->session_id()};
- delete $sw->{$self};
-
- unless (scalar keys %$sw) {
- delete $session_watchers{$self->name()};
-
- delete $session_watchers{$self->name()} unless (
- scalar keys %{$session_watchers{$self->name()}}
- );
-
- $self->stop_watching();
- }
-}
-
sub start_watching {
my $self = shift;
-
- return $POE::Kernel::poe_kernel->call(
- $self->session_id(), "call_gate", $self, "start_watching", @_
- ) if (
- $self->session_id() ne $POE::Kernel::poe_kernel->get_active_session()->ID()
- );
-
+ return unless $self->call_gate("start_watching");
$POE::Kernel::poe_kernel->sig($self->name(), "signal_happened");
}
sub stop_watching {
my $self = shift;
-
- return $POE::Kernel::poe_kernel->call(
- $self->session_id(), "call_gate", $self, "stop_watching", @_
- ) if (
- $self->session_id() ne $POE::Kernel::poe_kernel->get_active_session()->ID()
- );
-
+ return unless $self->call_gate("stop_watching");
$POE::Kernel::poe_kernel->sig($self->name(), undef);
$self->name(undef);
}
@@ -84,20 +57,24 @@ sub _deliver {
# If nobody's watching us, then why did we do it in the road?
return unless exists $session_watchers{$signal_name};
+ my %event_args = ( name => $signal_name );
+ if (exists $signal_param_names{$signal_name}) {
+ my $i = 0;
+ %event_args = (
+ map { $_ => $signal_args[$i++] }
+ @{$signal_param_names{$signal_name}}
+ );
+ }
+
+ # TODO - Ideally, %event_args would be calculated here based on
+ # $signal_name.
+
# Deliver the signal.
while (
my ($session_id, $stage_rec) = each %{$session_watchers{$signal_name}}
) {
foreach my $stage (values %$stage_rec) {
-
- # TODO - All stages here theoretically have the same class, and
- # therefore the same parameters. Don't recalculate %args.
- my $i = 0;
- my $param_names = $stage->event_param_names();
- my %event_args = map { $_ => $signal_args[$i++] } @$param_names;
- $event_args{name} = $signal_name;
-
$stage->emit(
event => 'signal',
args => \%event_args,
@@ -108,7 +85,24 @@ sub _deliver {
sub DEMOLISH {
my $self = shift;
- $self->stop_watching() if defined $self->name();
+
+ return unless defined $self->name();
+
+ my $sw = $session_watchers{$self->name()}->{$self->session_id()};
+ delete $sw->{$self};
+
+ unless (scalar keys %$sw) {
+ delete $session_watchers{$self->name()};
+
+ delete $session_watchers{$self->name()} unless (
+ scalar keys %{$session_watchers{$self->name()}}
+ );
+
+ $self->stop_watching();
+ }
}
+no Moose;
+__PACKAGE__->meta()->make_immutable();
+
1;
View
@@ -14,34 +14,22 @@ has 'pid' => (
default => sub { die "required" },
);
-sub event_param_names {
- return [qw(pid exit)];
-}
+__PACKAGE__->_register_signal_params(qw(pid exit));
sub start_watching {
my $self = shift;
-
- return $POE::Kernel::poe_kernel->call(
- $self->session_id(), "call_gate", $self, "start_watching", @_
- ) if (
- $self->session_id() ne $POE::Kernel::poe_kernel->get_active_session()->ID()
- );
-
+ return unless $self->call_gate("start_watching");
$POE::Kernel::poe_kernel->sig_child($self->pid(), "signal_happened");
}
sub stop_watching {
my $self = shift;
-
- return $POE::Kernel::poe_kernel->call(
- $self->session_id(), "call_gate", $self, "stop_watching", @_
- ) if (
- $self->session_id() ne $POE::Kernel::poe_kernel->get_active_session()->ID()
- );
-
+ return unless $self->call_gate("stop_watching");
$POE::Kernel::poe_kernel->sig_child($self->pid(), undef);
$self->name(undef);
}
-1;
+no Moose;
+__PACKAGE__->meta()->make_immutable();
+1;
View
@@ -6,4 +6,7 @@ with 'StageRole';
# Composes the StageRole role into a class.
# Does nothing of its own.
+no Moose;
+__PACKAGE__->meta()->make_immutable();
+
1;
Oops, something went wrong.

0 comments on commit 67e618a

Please sign in to comment.