r34029 - in /branches/upstream/libpoe-component-pubsub-perl: ./ current/ current/lib/ current/lib/POE/ current/lib/POE/Component/ current/t/

ryan52-guest at users.alioth.debian.org ryan52-guest at users.alioth.debian.org
Sat Apr 25 04:05:47 UTC 2009


Author: ryan52-guest
Date: Sat Apr 25 04:05:42 2009
New Revision: 34029

URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=34029
Log:
[svn-inject] Installing original source of libpoe-component-pubsub-perl

Added:
    branches/upstream/libpoe-component-pubsub-perl/
    branches/upstream/libpoe-component-pubsub-perl/current/
    branches/upstream/libpoe-component-pubsub-perl/current/Build.PL
    branches/upstream/libpoe-component-pubsub-perl/current/ChangeLog
    branches/upstream/libpoe-component-pubsub-perl/current/MANIFEST
    branches/upstream/libpoe-component-pubsub-perl/current/META.yml
    branches/upstream/libpoe-component-pubsub-perl/current/README
    branches/upstream/libpoe-component-pubsub-perl/current/lib/
    branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/
    branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/
    branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/PubSub.pm
    branches/upstream/libpoe-component-pubsub-perl/current/t/
    branches/upstream/libpoe-component-pubsub-perl/current/t/00-load.t
    branches/upstream/libpoe-component-pubsub-perl/current/t/01-basic.t

Added: branches/upstream/libpoe-component-pubsub-perl/current/Build.PL
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/Build.PL?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/Build.PL (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/Build.PL Sat Apr 25 04:05:42 2009
@@ -1,0 +1,19 @@
+use strict;
+use warnings;
+use Module::Build;
+
+my $builder = Module::Build->new(
+    module_name         => 'POE::Component::PubSub',
+    license             => 'gpl',
+    dist_author         => 'Nicholas R. Perez <nperez at cpan.org>',
+    dist_version_from   => 'lib/POE/Component/PubSub.pm',
+    create_readme       => 1,
+    build_requires => {
+        'perl'  => '5.10.0',
+        'Test::More' => 0,
+        'POE' => 1.003
+    },
+    add_to_cleanup      => [ 'POE-Component-PubSub-*' ],
+);
+
+$builder->create_build_script();

Added: branches/upstream/libpoe-component-pubsub-perl/current/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/ChangeLog?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/ChangeLog (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/ChangeLog Sat Apr 25 04:05:42 2009
@@ -1,0 +1,23 @@
+2009-03-20 nperez <nperez at cpan.org>
+	* Release: 0.05
+	* Clean up behaviors with regards event checking
+	* Fix warnings and bugs
+	* Add 'our $TRACE_AND_DEBUG;' ability
+
+2009-03-19 nperez <nperez at cpan.org>
+	* Release: 0.04
+	* Include a 'destroy' event to kill the session
+
+2009-03-12 nperez <nperez at cpan.org>
+	* New release: 0.03
+	* Enable 'input' published events
+	* Relax subscribing without publisher
+
+2008-12-27 nperez <nperez at cpan.org>
+	* Maintenance revision: 0.02
+	* Make sure Build.PL requires 5.10.0
+	* Make sure PubSub.pm does a backwards compat 'use 5.010;'
+
+2008-12-27 nperez <nperez at cpan.org>
+	* Initial release
+

Added: branches/upstream/libpoe-component-pubsub-perl/current/MANIFEST
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/MANIFEST?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/MANIFEST (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/MANIFEST Sat Apr 25 04:05:42 2009
@@ -1,0 +1,8 @@
+Build.PL
+ChangeLog
+MANIFEST
+META.yml # Will be created by "make dist"
+README
+lib/POE/Component/PubSub.pm
+t/00-load.t
+t/01-basic.t

Added: branches/upstream/libpoe-component-pubsub-perl/current/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/META.yml?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/META.yml (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/META.yml Sat Apr 25 04:05:42 2009
@@ -1,0 +1,24 @@
+---
+name: POE-Component-PubSub
+version: 0.05
+author:
+  - 'Nicholas R. Perez <nperez at cpan.org>'
+abstract: |-
+  A generic publish/subscribe POE::Component that 
+  enables POE::Sessions to publish events to which other POE::Sessions may 
+  subscribe.
+license: gpl
+resources:
+  license: http://opensource.org/licenses/gpl-license.php
+build_requires:
+  POE: 1.003
+  Test::More: 0
+  perl: 5.10.0
+provides:
+  POE::Component::PubSub:
+    file: lib/POE/Component/PubSub.pm
+    version: 0.05
+generated_by: Module::Build version 0.280801
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.2.html
+  version: 1.2

Added: branches/upstream/libpoe-component-pubsub-perl/current/README
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/README?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/README (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/README Sat Apr 25 04:05:42 2009
@@ -1,0 +1,153 @@
+NAME
+    POE::Component::PubSub - A generic publish/subscribe POE::Component that
+    enables POE::Sessions to publish events to which other POE::Sessions may
+    subscribe.
+
+VERSION
+    Version 0.04
+
+SYNOPSIS
+    # Instantiate the publish/subscriber with the alias "pub"
+    POE::Component::PubSub->new('pub');
+
+    # Publish an event called "FOO". +PUBLISH_OUTPUT is actually optional.
+    $_[KERNEL]->post('pub', 'publish', 'FOO', +PUBLISH_OUTPUT);
+
+    # Elsewhere, subscribe to that event, giving it an event to call # when
+    the published event is fired. $_[KERNEL]->post('pub', 'subscribe',
+    'FOO', 'FireThisEvent');
+
+    # Fire off the published event $_[KERNEL]->post('pub', 'FOO');
+
+    # Publish an 'input' event $_[KERNEL]->post('pub', 'publish', 'BAR',
+    +PUBLISH_INPUT, 'MyInputEvent');
+
+    # Tear down the whole thing $_[KERNEL]->post('pub', 'destroy');
+
+EVENTS
+    All public events do some sanity checking to make sure of a couple of
+    things before allowing the events such as checking to make sure the
+    posting session actually owns the event it is publishing, or that the
+    event passed as the return event during subscription is owned by the
+    sender. When one of those cases comes up, an error is carp'd, and the
+    event returns without stopping execution.
+
+    'publish'
+        This is the event to use to publish events. It accepts one argument,
+        the event to publish. The published event may not already be
+        previously published. The event may be completely arbitrary and does
+        not require the publisher to implement that event. Think of it as a
+        name for a mailing list.
+
+        You can also publish an 'input' or inverse event. This allows for
+        arbitrary sessions to post to your event. In this case, you must
+        supply the optional published event type and the event to be called
+        when the published event fires.
+
+        There are two types: PUBLISH_INPUT and PUBLISH_OUTPUT. PUBLISH_OUPUT
+        is implied when no argument is supplied.
+
+    'subscribe'
+        This is the event to use when subscribing to published events. It
+        accepts two arguments: 1) the published event, and 2) the event name
+        of the subscriber to be called when the published event is fired.
+        The event doesn't need to be published prior to subscription to
+        resolve chicken and egg problems in an async environment. But, the
+        sender must own and implement the return event.
+
+    'rescind'
+        Use this event to stop publication of an event. It accepts one
+        argument, the published event. The event must be published, and
+        published by the sender of the rescind event. If the published event
+        has any subscribers, a warning will be carp'd but execution will
+        continue.
+
+    'cancel'
+        Cancel subscriptions to events with this event. It accepts one
+        argment, the published event. The event must be published and the
+        sender must be subscribed to the event.
+
+    '_default'
+        After an event is published, the publisher may arbitrarily fire that
+        event to this component and the subscribers will be notified by
+        calling their respective return events with whatever arguments are
+        passed by the publisher. The event must be published, owned by the
+        publisher, and have subscribers for the event to be propagated. If
+        any of the subscribers no longer has a valid return event their
+        subscriptions will be cancelled and a warning will be carp'd.
+
+    'listing'
+        To receive an array reference containing tuples of the event name,
+        and the type of the events that are currently published within the
+        component, call this event. It accepts one argument, the return
+        event to fire with the listing. The sender must own the return
+        event.
+
+    'destroy'
+        This event will simply destroy any of its current state and remove
+        any and all aliases this session may have picked up. This should
+        free up the session for garbage collection.
+
+CLASS METHODS
+    POE::Component::PubSub->new($alias)
+        This is the constructor for the publish subscribe component. It
+        instantiates it's own session using the provided $alias argument to
+        set its kernel alias. If no alias is provided, the default alias is
+        'PUBLISH_SUBSCRIBE'.
+
+DEBUGGING
+    $POE::Component::PubSub::TRACE_AND_DEBUG
+        To enable debugging within the component at the POE::Session level
+        and also with various warnings, set this variable to logical true
+        BEFORE calling new().
+
+NOTES
+    Right now this component is extremely simple, but thorough when it comes
+    to checking the various requirements for publishing and subscribing.
+    Currently, there is no mechanism to place meta-subscriptions to the
+    events of the component itself. This feature is planned for the next
+    release.
+
+    Also, to do some of the checking on whether subscribers own the return
+    events, some ideas were lifted from POE::API::Peek, and like that
+    module, if there are changes to the POE core, they may break this
+    module.
+
+AUTHOR
+    Nicholas R. Perez, "<nperez at cpan.org>"
+
+BUGS
+    Please report any bugs or feature requests to "bug-poe-component-pubsub
+    at rt.cpan.org", or through the web interface at
+    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=POE-Component-PubSub>. I
+    will be notified, and then you'll automatically be notified of progress
+    on your bug as I make changes.
+
+SUPPORT
+    You can find documentation for this module with the perldoc command.
+
+        perldoc POE::Component::PubSub
+
+    You can also look for information at:
+
+    *   AnnoCPAN: Annotated CPAN documentation
+
+        <http://annocpan.org/dist/POE-Component-PubSub>
+
+    *   CPAN Ratings
+
+        <http://cpanratings.perl.org/d/POE-Component-PubSub>
+
+    *   RT: CPAN's request tracker
+
+        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=POE-Component-PubSub>
+
+    *   Search CPAN
+
+        <http://search.cpan.org/dist/POE-Component-PubSub>
+
+COPYRIGHT & LICENSE
+    Copyright 2008-2009 Nicholas R. Perez, all rights reserved.
+
+    This program is released under the following license: gpl
+

Added: branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/PubSub.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/PubSub.pm?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/PubSub.pm (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/lib/POE/Component/PubSub.pm Sat Apr 25 04:05:42 2009
@@ -1,0 +1,625 @@
+package POE::Component::PubSub;
+
+use 5.010;
+use warnings;
+use strict;
+use base('Exporter');
+
+our $VERSION = '0.05';
+
+use POE;
+use Carp;
+
+use constant
+{
+	'EVENTS'		    => 0,
+    'ALIAS'             => 1,
+    'PUBLISHER'         => 0,
+    'SUBSCRIBERS'       => 1,
+    'TYPE'              => 2,
+    'INPUT'             => 3,
+    'PUBLISH_INPUT'     => 0,
+    'PUBLISH_OUTPUT'    => 1,
+};
+
+our @EXPORT = qw/ PUBLISH_INPUT PUBLISH_OUTPUT /;
+
+our $TRACE_AND_DEBUG = 0;
+
+sub new()
+{
+	my $class = shift(@_);
+    my $alias = shift(@_);
+	my $self = [];
+	$self->[+EVENTS] = {};
+    $alias //= 'PUBLISH_SUBSCRIBE';
+
+    $self->[+ALIAS] = $alias;
+
+	bless($self, $class);
+
+	POE::Session->create
+	(
+		'object_states' =>
+		[
+			$self =>
+			[
+				'_start',
+				'_stop',
+				'_default',
+				'publish',
+				'subscribe',
+				'rescind',
+                'cancel',
+                'destroy',
+			]
+		],
+
+		'options' =>
+		{
+			'trace'	=>	$TRACE_AND_DEBUG,
+			'debug'	=>	$TRACE_AND_DEBUG,
+		}
+	);
+    
+    return $self;
+}
+
+sub _start()
+{
+    $_[KERNEL]->alias_set($_[OBJECT]->[+ALIAS]);
+}
+
+sub _stop()
+{
+    $_[KERNEL]->alias_remove($_) for $_[KERNEL]->alias_list();
+}
+
+sub _default()
+{
+    my ($kernel, $self, $sender, $event, $arg) = 
+        @_[KERNEL, OBJECT, SENDER, ARG0, ARG1];
+    
+    if($self->_event_exists($event))
+    {
+        if($self->_is_output($event))
+        {
+            if(!$self->_owns($sender->ID(), $event))
+            {
+                Carp::carp("Event [ $event ] is not owned by Sender: " . $sender->ID()) if $TRACE_AND_DEBUG;
+                return;
+            }
+
+            if(!$self->_has_subscribers($event))
+            {
+                Carp::carp('Event[ '.$event.' ] currently has no subscribers') if $TRACE_AND_DEBUG;
+                return;
+            }
+
+            while (my ($subscriber, $return) = each %{ $self->_get_subs($event) })
+            {
+                if(!$self->_has_event($subscriber, $return))
+                {
+                    Carp::carp("$subscriber no longer has $return in their events") if $TRACE_AND_DEBUG;
+                    $self->_remove_sub($subscriber, $event);
+                }
+                
+                $kernel->post($subscriber, $return, @$arg);
+            }
+            return;
+        }
+        else
+        {
+            $kernel->post(
+                $kernel->ID_id_to_session($self->_get_pub($event)), 
+                $self->_get_input($event), 
+                @$arg);
+        }
+    }
+    else
+    {
+        Carp::carp('Event [ '. $event . ' ] does not currently exist') if $TRACE_AND_DEBUG;
+        return;
+    }
+}
+
+sub destroy()
+{
+    my ($kernel, $self) = @_[KERNEL, OBJECT];
+
+    $self->[+EVENTS] = undef;
+    $kernel->alias_remove($_) for $kernel->alias_list();
+}
+
+sub listing()
+{
+    my ($kernel, $self, $sender, $return) = @_[KERNEL, OBJECT, SENDER, ARG1];
+
+    if(!defined($return))
+	{
+		Carp::carp('$event argument is required for listing') if $TRACE_AND_DEBUG;
+        return;
+	}
+    
+    if(!$self->_has_event($sender, $return))
+	{
+	    Carp::carp($sender . ' must own the ' . $return . ' event') if $TRACE_AND_DEBUG;
+        return;
+	}
+
+    my $events = $self->_all_published_events();
+
+    $kernel->post($sender, $return, $events);
+}
+
+sub publish()
+{
+	my ($kernel, $self, $sender, $event, $type, $input) =
+        @_[KERNEL, OBJECT, SENDER, ARG0, ARG1, ARG2];
+		
+	if(!defined($event))
+	{
+		Carp::carp('$event argument is required for publishing') if $TRACE_AND_DEBUG;
+        return;
+	}
+    
+    if($self->_event_exists($event))
+    {
+        if($self->_is_published($event))
+        {
+            Carp::carp('Event [ '. $event  .' ] already has a publisher') if $TRACE_AND_DEBUG;
+            return;
+        }
+        
+        if(defined($type) && $type == +PUBLISH_INPUT)
+        {
+            if(!$self->_has_event($sender, $input))
+            {
+                Carp::carp($sender . ' must own the ' . defined($input) ? $input : '' . ' event') if $TRACE_AND_DEBUG;
+                return;
+            }
+
+            if($self->_is_output($event))
+            {
+                Carp::carp('Event [ '. $event  .' ] already has a subscriber and precludes publishing') if $TRACE_AND_DEBUG;
+                return;
+            }
+        }
+    }
+
+    if(defined($type) && $type == +PUBLISH_INPUT)
+    {
+        if(!$self->_has_event($sender, $input))
+        {
+            Carp::carp($sender . ' must own the ' . defined($input) ? $input : '' . ' event') if $TRACE_AND_DEBUG;
+            return;
+        }
+    }
+
+	$self->_add_pub($sender->ID(), $event, $type, $input);
+	
+}
+
+sub subscribe()
+{
+	my ($kernel, $self, $sender, $event, $return) = 
+        @_[KERNEL, OBJECT, SENDER, ARG0, ARG1];
+
+	if(!defined($event))
+	{
+		Carp::carp('$event argument is required for subscribing') if $TRACE_AND_DEBUG;
+        return;
+	}
+    
+    if($self->_event_exists($event))
+    {
+        if(!$self->_is_output($event))
+        {
+            Carp::carp('Event[ '.$event.' ] is not an output event') if $TRACE_AND_DEBUG;
+            return;
+        }
+
+        if(!$self->_has_event($sender, $return))
+        {
+            Carp::carp($sender . ' must own the ' . $return . ' event') if $TRACE_AND_DEBUG;
+            return;
+        }
+    }
+
+    $self->_add_sub($sender->ID, $event, $return);
+}
+
+sub rescind()
+{
+    my ($kernel, $self, $sender, $event) = 
+        @_[KERNEL, OBJECT, SENDER, ARG0];
+
+    if(!defined($event))
+	{
+		Carp::carp('$event argument is required for rescinding') if $TRACE_AND_DEBUG;
+        return;
+	}
+    
+    if($self->_event_exists($event))
+    {
+        if(!$self->_is_published($event))
+        {
+            Carp::carp('Event[ '.$event.' ] is not published') if $TRACE_AND_DEBUG;
+            return;
+        }
+
+        if(!$self->_owns($sender->ID(), $event))
+        {
+            Carp::carp('Event[ '.$event.' ] is not owned by $sender') if $TRACE_AND_DEBUG;
+            return;
+        }
+
+        if($self->_has_subscribers($event))
+        {
+            Carp::carp('Event[ '.$event.' ] currently has subscribers, but removing anyway') if $TRACE_AND_DEBUG;
+        }
+        
+        $self->_remove_pub($sender->ID(), $event);
+    }
+}
+
+sub cancel()
+{
+    my ($kernel, $self, $sender, $event) = 
+        @_[KERNEL, OBJECT, SENDER, ARG0];
+    
+    if(!defined($event))
+	{
+		Carp::carp('$event argument is required for canceling') if $TRACE_AND_DEBUG;
+        return;
+	}
+
+    if($self->_event_exists($event))
+    {
+        if(!$self->_is_subscribed($sender->ID(), $event))
+        {
+            Carp::carp($sender . ' must be subscribed to the ' . $event . ' event') if $TRACE_AND_DEBUG;
+            return;
+        }
+
+        $self->_remove_sub($sender->ID(), $event);
+    }
+}
+
+# EVIL: We need to do some checking to make sure subscribers actually have the 
+# events they claim to have. I didn't want to have a dependency on 
+# POE::API::Peek and the subsequent Devel::Size, so I ripped out what concepts
+# I needed to implement this.
+sub _events()
+{
+	my ($self, $session) = @_;
+	
+	if(uc(ref($session)) =~ m/POE::SESSION/)
+	{
+		return [ keys( %{ $session->[ &POE::Session::SE_STATES() ] } ) ] ;
+	
+	} else {
+		
+		my $ref = $poe_kernel->ID_id_to_session($session);
+
+		if(defined($ref))
+		{
+			return [ keys( %{ $ref->[ &POE::Session::SE_STATES() ] } ) ];
+		
+		} else {
+
+			return undef;
+		}
+	}
+}
+
+sub _has_event()
+{
+	my ($self, $session, $event) = @_;
+
+    return 0 if not defined($event);
+    my $events = $self->_events( $session );
+
+    if(defined($events))
+    {
+	    return scalar( grep( m/$event/, @{ $events } ) );
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+sub _event_exists()
+{
+    return exists($_[0]->[+EVENTS]->{$_[1]});
+}
+
+sub _is_output()
+{
+    my ($self, $event) = @_;
+    return $self->[+EVENTS]->{$event}->[+TYPE] == +PUBLISH_OUTPUT;
+}
+
+sub _has_subscribers()
+{
+    my ($self, $event) = @_;
+    return scalar( keys %{ $self->[+EVENTS]->{$event}->[+SUBSCRIBERS] } ) ;
+}
+
+sub _is_published()
+{
+    my ($self, $event) = @_;
+    return defined($self->[+EVENTS]->{$event}->[+PUBLISHER]);
+}
+
+sub _is_subscribed()
+{
+    my ($self, $subscriber, $event) = @_;
+    return 0 if not defined($subscriber);
+    return exists($self->[+EVENTS]->{$event}->[+SUBSCRIBERS]->{$subscriber});
+}
+
+sub _owns()
+{
+    my ($self, $publisher, $event) = @_;
+    return 0 if not defined($publisher);
+    return 0 if not defined($self->[+EVENTS]->{$event}->[+PUBLISHER]);
+    return $self->[+EVENTS]->{$event}->[+PUBLISHER] eq $publisher;
+}
+
+sub _add_pub()
+{
+    my ($self, $publisher, $event, $type, $input) = @_;
+    if(!exists($self->[+EVENTS]->{$event}))
+    {
+        $self->[+EVENTS]->{$event} = [];
+        $self->[+EVENTS]->{$event}->[+SUBSCRIBERS] = {};
+    }
+    $self->[+EVENTS]->{$event}->[+PUBLISHER] = $publisher;
+    $self->[+EVENTS]->{$event}->[+TYPE] = $type // +PUBLISH_OUTPUT;
+    $self->[+EVENTS]->{$event}->[+INPUT] = $input;
+    return;
+}
+
+sub _add_sub()
+{
+    my ($self, $subscriber, $event, $return) = @_;
+    if(!exists($self->[+EVENTS]->{$event}))
+    {
+        $self->[+EVENTS]->{$event} = [];
+        $self->[+EVENTS]->{$event}->[+SUBSCRIBERS] = {};
+    }
+    $self->[+EVENTS]->{$event}->[+SUBSCRIBERS]->{$subscriber} = $return;
+    $self->[+EVENTS]->{$event}->[+TYPE] = +PUBLISH_OUTPUT;
+    return;
+}
+
+sub _del_sub()
+{
+    my ($self, $subscriber, $event) = @_;
+    delete($self->[+EVENTS]->{$event}->[+SUBSCRIBERS]->{$subscriber});
+    return;
+}
+
+sub _del_pub()
+{
+    my ($self, $publisher, $event) = @_;
+    delete($self->[+EVENTS]->{$event});
+    return;
+}
+
+sub _get_subs()
+{
+    my ($self, $event) = @_;
+    return $self->[+EVENTS]->{$event}->[+SUBSCRIBERS];
+}
+
+sub _get_pub()
+{
+    my ($self, $event) = @_;
+    return $self->[+EVENTS]->{$event}->[+PUBLISHER];
+}
+
+sub _get_input()
+{
+    my ($self, $event) = @_;
+    return $self->[+EVENTS]->{$event}->[+INPUT];
+}
+
+sub _all_published_events()
+{
+    my ($self) = @_;
+    return [ map { [$_, $self->[+EVENTS]->{$_}->[+INPUT]] } sort keys %{$self->[+EVENTS]} ];
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+POE::Component::PubSub - A generic publish/subscribe POE::Component that 
+enables POE::Sessions to publish events to which other POE::Sessions may 
+subscribe.
+
+=head1 VERSION
+
+Version 0.04
+
+=head1 SYNOPSIS
+
+# Instantiate the publish/subscriber with the alias "pub"
+POE::Component::PubSub->new('pub');
+
+# Publish an event called "FOO". +PUBLISH_OUTPUT is actually optional.
+$_[KERNEL]->post('pub', 'publish', 'FOO', +PUBLISH_OUTPUT);
+
+# Elsewhere, subscribe to that event, giving it an event to call
+# when the published event is fired.
+$_[KERNEL]->post('pub', 'subscribe', 'FOO', 'FireThisEvent');
+
+# Fire off the published event
+$_[KERNEL]->post('pub', 'FOO');
+
+# Publish an 'input' event
+$_[KERNEL]->post('pub', 'publish', 'BAR', +PUBLISH_INPUT, 'MyInputEvent');
+
+# Tear down the whole thing
+$_[KERNEL]->post('pub', 'destroy');
+
+
+=head1 EVENTS
+
+All public events do some sanity checking to make sure of a couple of things
+before allowing the events such as checking to make sure the posting session
+actually owns the event it is publishing, or that the event passed as the
+return event during subscription is owned by the sender. When one of those 
+cases comes up, an error is carp'd, and the event returns without stopping
+execution.
+
+=over 4
+
+=item 'publish'
+
+This is the event to use to publish events. It accepts one argument, the event
+to publish. The published event may not already be previously published. The
+event may be completely arbitrary and does not require the publisher to
+implement that event. Think of it as a name for a mailing list.
+
+You can also publish an 'input' or inverse event. This allows for arbitrary
+sessions to post to your event. In this case, you must supply the optional
+published event type and the event to be called when the published event fires. 
+
+There are two types: PUBLISH_INPUT and PUBLISH_OUTPUT. PUBLISH_OUPUT is implied
+when no argument is supplied.
+
+=item 'subscribe'
+
+This is the event to use when subscribing to published events. It accepts two
+arguments: 1) the published event, and 2) the event name of the subscriber to
+be called when the published event is fired. The event doesn't need to be  
+published prior to subscription to resolve chicken and egg problems in an async
+environment. But, the sender must own and implement the return event.
+
+=item 'rescind'
+
+Use this event to stop publication of an event. It accepts one argument, the 
+published event. The event must be published, and published by the sender of
+the rescind event. If the published event has any subscribers, a warning will
+be carp'd but execution will continue.
+
+=item 'cancel'
+
+Cancel subscriptions to events with this event. It accepts one argment, the
+published event. The event must be published and the sender must be subscribed
+to the event.
+
+=item '_default'
+
+After an event is published, the publisher may arbitrarily fire that event to
+this component and the subscribers will be notified by calling their respective
+return events with whatever arguments are passed by the publisher. The event 
+must be published, owned by the publisher, and have subscribers for the event
+to be propagated. If any of the subscribers no longer has a valid return event
+their subscriptions will be cancelled and a warning will be carp'd.
+
+=item 'listing'
+
+To receive an array reference containing tuples of the event name, and the type
+of the events that are currently published within the component, call this 
+event. It accepts one argument, the return event to fire with the listing. The 
+sender must own the return event.
+
+=item 'destroy'
+
+This event will simply destroy any of its current state and remove any and all
+aliases this session may have picked up. This should free up the session for
+garbage collection.
+
+=back
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item POE::Component::PubSub->new($alias)
+
+This is the constructor for the publish subscribe component. It instantiates
+it's own session using the provided $alias argument to set its kernel alias. 
+If no alias is provided, the default alias is 'PUBLISH_SUBSCRIBE'.
+
+=back
+
+=head1 DEBUGGING
+
+=over 4
+
+=item $POE::Component::PubSub::TRACE_AND_DEBUG
+
+To enable debugging within the component at the POE::Session level and also
+with various warnings, set this variable to logical true BEFORE calling new().
+
+=back
+
+=head1 NOTES
+
+Right now this component is extremely simple, but thorough when it comes to 
+checking the various requirements for publishing and subscribing. Currently, 
+there is no mechanism to place meta-subscriptions to the events of the 
+component itself. This feature is planned for the next release.
+
+Also, to do some of the checking on whether subscribers own the return events,
+some ideas were lifted from POE::API::Peek, and like that module, if there are
+changes to the POE core, they may break this module. 
+
+=head1 AUTHOR
+
+Nicholas R. Perez, C<< <nperez at cpan.org> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-poe-component-pubsub at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=POE-Component-PubSub>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc POE::Component::PubSub
+
+You can also look for information at:
+
+=over 4
+
+=item * AnnoCPAN: Annotated CPAN documentation
+
+L<http://annocpan.org/dist/POE-Component-PubSub>
+
+=item * CPAN Ratings
+
+L<http://cpanratings.perl.org/d/POE-Component-PubSub>
+
+=item * RT: CPAN's request tracker
+
+L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=POE-Component-PubSub>
+
+=item * Search CPAN
+
+L<http://search.cpan.org/dist/POE-Component-PubSub>
+
+=back
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2008-2009 Nicholas R. Perez, all rights reserved.
+
+This program is released under the following license: gpl
+
+=cut
+

Added: branches/upstream/libpoe-component-pubsub-perl/current/t/00-load.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/t/00-load.t?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/t/00-load.t (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/t/00-load.t Sat Apr 25 04:05:42 2009
@@ -1,0 +1,9 @@
+#!perl -T
+
+use Test::More tests => 1;
+
+BEGIN {
+	use_ok( 'POE::Component::PubSub' );
+}
+
+diag( "Testing POE::Component::PubSub $POE::Component::PubSub::VERSION, Perl $], $^X" );

Added: branches/upstream/libpoe-component-pubsub-perl/current/t/01-basic.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libpoe-component-pubsub-perl/current/t/01-basic.t?rev=34029&op=file
==============================================================================
--- branches/upstream/libpoe-component-pubsub-perl/current/t/01-basic.t (added)
+++ branches/upstream/libpoe-component-pubsub-perl/current/t/01-basic.t Sat Apr 25 04:05:42 2009
@@ -1,0 +1,127 @@
+use feature ':5.10';
+use warnings;
+use strict;
+
+use Test::More tests => 10;
+use POE;
+
+BEGIN
+{
+    use_ok('POE::Component::PubSub');
+}
+
+isa_ok(POE::Component::PubSub->new('pub_alias'), 'POE::Component::PubSub');
+
+POE::Session->create
+(
+    'inline_states' =>
+    {
+        '_start' => sub
+        {
+            $_[KERNEL]->alias_set('runner');
+            $_[KERNEL]->yield('continue');
+        },
+        
+        'continue' => sub
+        {
+            make_publisher();
+            make_subscriber();
+
+            $_[KERNEL]->post('test1', 'fire');
+        },
+    }
+);
+
+POE::Kernel->run();
+
+exit 0;
+
+sub make_publisher()
+{
+    POE::Session->create
+    (
+        'inline_states' =>
+        {
+            '_start' => sub
+            {
+                $_[KERNEL]->alias_set('test1');
+                $_[KERNEL]->yield('publisher');
+            },
+            
+            'publisher' => sub
+            {
+                $_[KERNEL]->post('pub_alias', 'publish', 'foo');
+                $_[KERNEL]->post('pub_alias', 'publish', 'bar', +PUBLISH_INPUT, 'input');
+                pass('Published');
+            },
+
+            'fire' => sub
+            {
+                $_[KERNEL]->post('pub_alias', 'foo', 'ARGUMENT');
+                pass('Event fired');
+            },
+
+            'input' => sub
+            {
+                pass('input event fired');
+
+                if(defined($_[ARG0]))
+                {
+                    if($_[ARG0] == 1)
+                    {
+                        pass('input argument okay');
+                        $_[KERNEL]->alias_remove('test1');
+                        $_[KERNEL]->call('pub_alias', 'destroy');
+                        $_[KERNEL]->yield('destroyed');
+                        return;
+                    }
+                }
+                fail('input argument not okay');
+            },
+
+            'destroyed' => sub
+            {
+                if(!$_[KERNEL]->post('pub_alias', 'nonexistant_events'))
+                {
+                    pass('destroy works');
+                }
+                else
+                {
+                    fail('destroy does not work appropriate');
+                }
+            }
+        }
+    );
+}
+
+sub make_subscriber()
+{
+    POE::Session->create
+    (
+        'inline_states' =>
+        {
+            '_start' => sub
+            {
+                $_[KERNEL]->alias_set('test2');
+                $_[KERNEL]->yield('subscriber');
+            },
+            
+            'subscriber' => sub
+            {
+                $_[KERNEL]->post('pub_alias', 'subscribe', 'foo', 'fired_event');
+                pass('Subscribed');
+            },
+
+            'fired_event' => sub
+            {
+                pass('Event received');
+
+                ok($_[ARG0] eq 'ARGUMENT', 'Argument passed successfully');
+                
+                $_[KERNEL]->post('pub_alias', 'bar', 1);
+                $_[KERNEL]->alias_remove('test2');
+            }
+        }
+    );
+}
+        




More information about the Pkg-perl-cvs-commits mailing list