Skip to content
Browse files

Support posting events to POE components from stages.

  • Loading branch information...
1 parent f868e68 commit 9bd513c381562e3cbc5f263168bdf7aa6b8375f3 @rcaputo committed Sep 18, 2009
Showing with 165 additions and 0 deletions.
  1. +66 −0 docs/PoCoEvent.pm
  2. +49 −0 docs/PoeEvent.pm
  3. +50 −0 docs/eg-12-poco-event.pl
View
66 docs/PoCoEvent.pm
@@ -0,0 +1,66 @@
+package PoCoEvent;
+
+# A component that accepts an event name to which return messages are
+# posted. In this case, the component builds a postback for the
+# calling session, which makes a more complex but satisfying test
+# case.
+#
+# TODO - Refactor into a base class and subclasses. This is only a
+# couple lines different from PoCoPostback.
+
+use warnings;
+use strict;
+use POE;
+
+sub new {
+ my $class = shift;
+
+ my $self = bless { }, $class;
+
+ my $result = 'aaaaaaaa';
+
+ POE::Session->create(
+ inline_states => {
+ _start => sub {
+ # Set an alias based on the object that owns us.
+ $_[HEAP]{alias} = "$self";
+ $_[KERNEL]->alias_set("$self");
+ },
+ shutdown => sub {
+ # Shutdown is triggered by the object DESTROY.
+ # Remove the alias, and gracefully exit when all pending
+ # timers are done.
+ $_[KERNEL]->alias_remove($_[HEAP]{alias});
+ },
+ request => sub {
+ # Handle a request. Feign some work.
+ my $event = $_[ARG0];
+ my $postback = $_[SENDER]->postback($event);
+ $_[KERNEL]->delay_add(
+ work_done => rand(3) => $postback => $result++
+ );
+ },
+ work_done => sub {
+ # When the work is done, post back a result.
+ my ($postback, $result) = @_[ARG0, ARG1];
+ $postback->($result);
+ },
+ },
+ );
+
+ return $self;
+}
+
+# Clean up the session on destruction.
+sub DESTROY {
+ my $self = shift;
+ $poe_kernel->call("$self", "shutdown");
+}
+
+# Convenience method. Hide POE::Kernel->post.
+sub request {
+ my ($self, $postback) = @_;
+ $poe_kernel->post("$self", "request", $postback);
+}
+
+1;
View
49 docs/PoeEvent.pm
@@ -0,0 +1,49 @@
+package PoeEvent;
+
+use Moose;
+use Carp qw(croak);
+
+has stage => (
+ is => 'ro',
+ isa => 'Stage',
+);
+
+has method => (
+ is => 'rw',
+ isa => 'Str',
+);
+
+has context => (
+ is => 'rw',
+ isa => 'HashRef',
+);
+
+sub BUILD {
+ my $self = shift;
+
+ if (
+ $POE::Kernel::poe_kernel->get_active_session()->ID()
+ ne
+ $self->stage()->session_id()
+ ) {
+ croak(
+ "When interfacing with POE at large, ", __PACKAGE__, " must\n",
+ "be created within a Stage's session. Perhaps invoke it within\n",
+ "the stage's run_within_session() method",
+ );
+ }
+}
+
+sub deliver {
+ my ($self, $args) = @_;
+
+ $POE::Kernel::poe_kernel->post(
+ $self->stage()->session_id(), "call_gate_method",
+ $self->stage(), $self->method(), {
+ passthrough => $self->context(),
+ callback => [ @$args ],
+ }
+ );
+}
+
+1;
View
50 docs/eg-12-poco-event.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+
+# Exercise the PoeEvent class, for passing events into POE space.
+
+{
+ package App;
+
+ use Moose;
+ extends 'Stage';
+ use PoeEvent;
+ use PoCoEvent;
+
+ has component => (
+ isa => 'Object|Undef',
+ is => 'rw',
+ );
+
+ sub BUILD {
+ my $self = shift;
+ $self->component( PoCoEvent->new() );
+
+ $self->run_within_session(
+ sub {
+ $self->component->request(
+ PoeEvent->new(
+ stage => $self,
+ method => "on_component_result",
+ context => { cookie => 123 },
+ ),
+ );
+ }
+ );
+ }
+
+ sub on_component_result {
+ my ($self, $args) = @_;
+ print(
+ "Got component response:\n",
+ " pass-through cookie: $args->{passthrough}{cookie}\n",
+ " call-back result : $args->{callback}[1][0]\n",
+ );
+
+ # Ok, we're done.
+ $self->component(undef);
+ }
+}
+
+my $app = App->new();
+$app->run_all();
+exit;

0 comments on commit 9bd513c

Please sign in to comment.
Something went wrong with that request. Please try again.