Over the years, one pattern shows up very often POE development : that of of registering sessions for certain events. Maybe as for of monitoring, or to subscribe to a service, or whatever. PoCo::Registry is an attempt to create one module to do this. Roughly, a session creates a registry key. It becomes the key owner. Other sessions may then register a todo (event or coderef) that key, and a verb (that is, a sub-key). The owning session may then get a list of those registred, or just trigger a key/verb tuple. Only the registering or owning session may unregister itself. Only the owning session may delete a key. So, a session may own one or more keys in the registry. Each key has one or more verbs. Other sessions sign-up for a key-verb pair. The owning session may list or trigger any of it's key-verb pairs. The (there is only one) registry is an association between key-verb pairs and a list of signed up sessions. Note that if you never use trigger() (see below) you can store anything you pretty much want in the registry. API === Startup ------- PoCo::Registry->spawn([$key[, $matcher]]); Create the registry session. There is only one registry. You can NOT change the alias of the registry. So :-P. $key, if given, creates a registry key of that name. This is to avoid always going PoCo::Registry->spawn(); $kernel->post(registry=>'create_key', $key, $matcher); Creation -------- Registry->create_key($key[, $matcher]); $kernel->post(registry=>'create_key', $key[, $matcher]); Creates a new registry key that sessions may sign up for. $matcher is a coderef that is used to see if any 2 $verbs match. It defaults to the equivalent of sub { $_[0] eq $_[1]}, ie 2 $verbs match if they are the same. I say "equivalent" because I'll probably optimise this as a hash lookup. Destruction ----------- Registry->delete_key([$key]); $kernel->post(registry=>'delete_key'[, $key]); Deletes a registry key. Only the creating session may remove a key. If key isn't specified, all keys for calling session are deleted. Signup ------ Registry->signup($key, $verb[, $todo]); $kernel->post(registry=>'signup', $key, $verb[, $todo]); Signs a session up to a $key/$verb. $todo is an optional "what to do" magic param. If it is a scalar is is assumed to be an event name coderef it is called arrayref it is assumed to be [$session, $event[, $params]] hashref GO AWAY typeglob NO WRONG! Cancel ------ Registry->remove([$key[, $verb[, $todo]]] $kernel->post(registry=>'remove'[, $key[, $verb[, $todo]]]); Removes a session from what it was subscribed to. $key if missing, removes *all* session's events $verb if missing, removes all the session's events in $key $todo if given, only removes that instance of a session's events List ---- @array=Registry->list([$key[, $verb]]) @array=$kernel->call(registry=>'list'[, $key[, $verb]]); Returns a list of of all sessions subscribed to a given $key/$verb. Note that it doesn't return the $todo above : use 'trigger' if you want that. $verb if missing, lists all verbs for that $key $key if missing, lists all keys for calling session Note that this requires the much maligned $kernel->call() Posting ------- Registry->trigger($key, $verb[, $data]); $kernel->trigger(registry=>'trigger', $key, $verb[, $data]); More often then not, the registry is used to hold a list of sessions that are interested in a given event (say for monitoring). This allows an owner session to post/call/leverage the $todo explained above. If $data is given, it is passed as an additional parameter to the events and/or coderef. Shutdown -------- Registry->shutdown(); $kernel->post(registry=>'shutdown'); Tell the registry session to GO AWAY AND STOP BOTHERING US. Syntatic sugar -------------- $coderef=Registry->mk_signup($key, [$verb]); $coderef=Registry->mk_remove($key, [$verb]); Creates a coderef that you could use as a POE event to allow sessions to sign-up and remove themselves from a $key-$verb tupple. ARG0 is the todo. If $verb is omited, ARG0 is the $verb and ARG1 is the todo. IN OTHER WORDS my $honk=POE::Session->create( # .... subscribe_midnight=>Registry->mk_signup('clock', 'midnight'), unsubscribe_midnight=>Registry->mk_remove('clock', 'midnight'), subscribe=>Registry->mk_signup('clock'), unsubscribe=>Registry->mk_signup('clock'), # .... ); # and in another session $kernel->post($honk, subscribe_midnight=>[$_[SESSION, 'it_TIME']); # it_TIME is posted when $honk triggers clock/midnight $kernel->post($honk, subscribe=>'chime', sub { .... }); # the coderef is called when $honk triggers clock/chime EXAMPLES -------- package MySession; use PoCo::Registry qw(Registry); Registry->spawn(); POE::Session->create( # .... _start=>sub { Registry->create_key('clock'); $kernel->delay_set('time', $TEN_MINUTES); }, time=>sub { $kernel->delay_set('time', $TEN_MINUTES); Registry->trigger(clock=>'ticker', time()); if($is_midnight) { Registry->trigger(clock=>'midnight'); } if($on_the_hour) { Registry->trigger(clock=>'chime'); } }, _stop=>sub { Registry->delete_key(); } # .... ); package MyOtherSession; POE::Session->create( # .... _start=>sub { Registry->signup(clock=>'ticker', 'tick'); Registry->signup(clock=>'midnight', 'honk'); }, tick=>sub { my($heap, $now)=@_[HEAP, ARG0]; } honk=>sub { print "HONK HONK HONK it's midnight HONK!"; } # .... ); package YetAnotherSession; POE::Session->create( # .... _start=>sub { Registry->signup(clock=>'ticker', sub { $kernel->yeild('tock', $N, @_)}); }, tock=>sub { # note that $now is now ARG1, ARG0 being $N in the closure above my($heap, $N, $now)=@_[HEAP, ARG0, ARG1]; } # .... );