Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
IKC::Responder(3)     User Contributed Perl Documentation    IKC::Responder(3)

       POE::Component::IKC::Responder -	POE IKC	state handler

	   use POE;
	   use POE::Component::IKC::Responder;
	   $kernel->post('IKC',	'post',	$to_state, $state);

	   $ikc->publish('my_name', [qw(state1 state2 state3)]);

       This module implements POE IKC state handling.  The responder handles
       posting states to foreign kernels and calling states in the local
       kernel at the request of	foreign	kernels.

       There are 2 interfaces to the responder.	 Either	by sending states to
       the 'IKC' session or the	object interface.  While the latter is faster,
       the better behaved, because POE is a cooperative	system.


       This function creates the Responder session and object.	Normally,
       POE::Component::IKC::Client or POE::Component::IKC::Server does this
       for you.	 But in	some applications you want to make sure	that the
       Responder is up and running before then.

       Sends an	state request to a foreign kernel.  Returns logical true if
       the state was sent and logical false if it was unable to	send the
       request to the foreign kernel.  This does not mean that the foreign
       kernel was able to post the state, however.  Parameters are as follows

	 Specifier for the foreign state.   See

	 A reference to	anything you want the foreign state to get as ARG0.
	 If you	want to	specify	several	parameters, use	an array ref and have
	 the foreign state dereference it.

	     $kernel->post('IKC', 'post',
		 {kernel=>'Syslog', session=>'logger', state=>'log'},
		 [$faculty, $priority, $message];


	     $ikc->post('poe://Syslog/logger/log', [$faculty, $priority, $message]);

	 This logs an state with a hypothetical	logger.

       See the "PROXY SENDER" below.

       This is identical to "post", except it has a 3rd	parameter that
       describes what state should receive the return value from the foreign

	   $kernel->post('IKC',	'call',
		       'poe://Pulse/timeserver/time', '',


	   $ikc->call({kernel=>'Pulse',	session=>'timeserver', state=>'time'},
		       '', 'poe://me/get_time');

       This asks the foreign kernel 'Pulse' for	the time.  'get_time' state in
       the current session is posted with whatever the foreign state returned.

       You do not have to publish callback messages, because they are
       temporarily published.  How temporary?  They can	be posted from a
       remote kernel ONCE only.	 This, of course, is a problem because someone
       else could get in a post	before the callback.  Such is life.

	  Identical to the "post" "foreign_state" parameter.

	  Identical to the "post" "parameters" parameter.

	  Event	identification for the callback.  That is, this	state is
	  called with the return value of the foreign state.  Can be a
	  "foreign_state" specifier or simply the name of an state in the
	  current session.

	   $kernel->call('IKC',	'post',
	       {kernel=>'e-comm', session=>'CC', state=>'check'},
	       {CC=>$cc, expiry=>$expiry}, folder=>$holder},
	   # or
	       {CC=>$cc, expiry=>$expiry}, folder=>$holder},

       This asks the e-comm server to check if a credit	card number is "well
       formed".	 Yes, this would probably be massive overkill.

       The "rsvp" state	does not need to be published.	IKC keeps track	of the
       rsvp state and will allow the foreign kernel to post to it.

       See the "PROXY SENDER" below.

       Sets the	default	foreign	kernel.	 You must be connected to the foreign
       kernel first.

       Unique parameter	is the name of the foreign kernel kernel.

       Returns logical true on success.

       Registers foreign kernel	names with the responder.  This	is done	during
       the negociation phase of	IKC and	is normaly handled by "IKC::Channel".
       Will define the default kernel if no previous default kernel exists.

       First parameter is either a single kernel name.	Second optional
       parameter is an array ref of kernel aliases to be registered.

       Unregisters one or more foreign kernel names with the responder.	 This
       is done when the	foreign	kernel disconnects by
       POE::Component::IKC::Channel.  If this is the default kernel, there is
       no more default kernel.

       First parameter is either a single kernel name or a kernel alias.
       Second optional parameter is an array ref of kernel aliases to be
       unregistered.  This second parameter is a tad silly, because if you
       unregister a remote kernel, it goes without saying that all it's
       aliases get unregistered	also.

       Registers new aliases for local kernel with the responder.  This	is
       done internally by POE::Component::IKC::Server and
       POE::Component::IKC::Client. Will NOT define the	default	kernel.

       First and only parameter	is an array ref	of kernel aliases to be

       Tell IKC	that some states in the	current	session	are available for use
       by foreign sessions.

	 A session alias by which the foreign kernels will call	it.  The alias
	 must already have been	registered with	the local kernel.

	 Arrayref of states that foreign kernels may post.

	     $kernel->post('IKC', 'publish', 'me', [qw(foo bar baz)]);
	     # or
	     $ikc->publish('me', [qw(foo bar baz)]);

       Tell IKC	that some states should	no longer be available for use by
       foreign sessions.  You do not have to retract all published states.

	 Same as in "publish"

	 Same as in "publish".	If not supplied, *all* published states	are

	     $kernel->post('IKC', 'retract', 'me', [qw(foo mibble dot)]);
	     # or
	     $ikc->retract('me', [qw(foo)]);

	   $list=$kernel->call(IKC=>'published', $session);

       Returns a list of all the published states.


       Returns a hashref, keyed	on session IDs.	 Values	are arrayref of	states
       published by that session.

	 A session alias that you wish the list	of states for.

       Subscribe to foreign sessions or	states.	 When you have subscribed to a
       foreign session,	a proxy	session	is created on the local	kernel that
       will allow you to post to it like any other local session.

	  An arrayref of the session or	state specifiers you wish to subscribe
	  to.  While the wildcard '*' kernel may be used, only the first
	  kernel that acknowledges the subscription will be proxied.

	  Either a state (for the state	interface) or a	coderef	(for the
	  object interface) that is posted (or called) when all	subscription
	  requests have	either been replied to,	or have	timed out.

	  When called, it has a	single parameter, an arrayref of all the
	  specifiers that IKC was able to subscribe to.	 It is up to you to
	  see if you have enough of the	foreign	sessions or states to get the
	  job done, or if you should give up.

	  While	"callback" isn't required, it makes a lot of sense to use it
	  because it is	only way to find out when the proxy sessions become

	  Example :

		      sub { $kernel->post('poe://Pulse/timeserver', 'connect') });

	  (OK, that's a	bad example because we don't check if we actually
	  managed to subscribe or not.)

	      $kernel->post('IKC', 'subscribe',
			      [qw(poe://e-comm/CC poe://TouchNet/validation
				  poe://Cantax/JDE poe://Informatrix/JDE)
	      #	and in state 'subscribed'
	      sub subscribed
		  my($kernel, $specs)=@_[KERNEL, ARG0];
		  if(@$specs !=	4)
		      die "Unable to find all the foreign sessions needed";
		  $kernel->post('poe://Cantax/JDE', 'write', {...somevalues...});

	  This is a bit	of a mess.  You	might want to use the "subscribe"
	  parameter to "spawn" instead.

	  Subscription receipt timeout is currently set	to 120 seconds.

       Reverse of the "subscribe" method.  However, it is currently not
       documented well.

       Responds	with 'PONG'.  This is auto-published, so it can	be called from
       remote kernels to see if	the local kernel is still around.  In fact, I
       don't see any other use for this.

	   $kernel->post('poe://remote/IKC', 'ping', 'some_state');
	   $kernel->delay('some_state',	60);   # timeout

	   sub some_state
	       return if $pong;		   # all is cool

	       # YOW!  Remote kernel timed out.	 RUN AROUND SCREAMING!

       Hopefully causes	IKC and	all peripheral sessions	to dissapear in	a puff
       of smoke.  At the very least, any sessions left will be either not
       related to IKC or barely	breathing (that	is, only have aliases keeping
       them from GC).  This should allow you to	sanely shut down your process.

       Allows a	session	to monitor the state of	remote kernels.	 Currently, a
       session is informed when	a remote kernel	is registered, unregistered,
       subscribed to or	unsubscribed from.  One	should make sure that the IKC
       alias exists before trying to monitor.  Do this by calling
       POE::Component::IKC::Responder->spawn or	in an "on_connect" callback.

	   $kernel->post('IKC',	'monitor', $remote_kernel_id, $states);

	  Name or alias	or IKC specifier of the	remote kernel you wish to
	  monitor.  You	can also specify "*" to	monitor	ALL remote kernels.
	  If you do, your monitor will be called several times for a given
	  kernel.  This	is because a kernel has	one name and many aliases.
	  For example, a remote	kernel will have a unique ID within the	local
	  kernel, a name (passed to or generated by
	  create_ikc_{kernel,client}) and a globaly unique ID assigned by the
	  remote kernel	via $kernel->ID.  This suprises	some people, but see
	  the short note after the explanation of the callback parameters.

	  Note:	An effort has been made	to insure that when monitoring "*",
	  "register" is	first called with the remote kernel's unique ID, and
	  subsequent calls are aliases.	 This can't be guaranteed at this
	  time,	however.

	  Hashref that specifies what callback states are called when
	  something interesting	happens.  If $state is empty or	undef, the
	  session will no longer monitor the given remote kernel.

   Callback states
       The following states can	be monitored:

	     Called when a channel becomes ready or goes away.	ARG3 is	either
	     "ready" or	"close".  ARG4 is the numerical	ID of the channel's
	     session.  See "CHANNELS" below.

	     Called when a remote kernel or alias is registered.  This is
	     equivalent	to when	the connection phase is	finished.

	     Called when a remote kernel or alias is unregistered.  This is
	     equivalent	to when	the remote kernel disconnects.

	     Called when IKC succeeds in subscribing to	a remote session.
	     ARG3 is an	IKC::Specifier of what was subscribed to.  Use this
	     for posting to the	proxy session.

	     Called when IKC succeeds in unsubscribing from a remote session.

	     You are informed whenever someone tries to	do a sane shutdown of
	     IKC and all peripheral sessions.  This will called	only once,
	     after somebody posts an IKC/shutdown event.

	     You are informed of errors	in local and remote kernels.  ARG3 is
	     the operation that	failed.	ARG4 is	the error message.  See
	     "ERRORS" below.

	     Little bit	of data	(can be	scalar or reference) that is passed to
	     the callback.  This allows	you to more magic.

       The callback states are called the following parameters :

	     Name of the kernel	that was passed	to poe://*/IKC/monitor

	     ID	or alias of remote kernel from IKC's point of view.

	     A flag.  If this is true, then ARG1 is the	remote kernel unique
	     ID, if false, then	ARG1 is	an alias.  This	is mostly useful when
	     monitoring	"*" and	is in fact a bit bloatful.

	     "$state->{data}" ie any data you want.

       "ARG4" ... "ARGN"
	     Callback-specific parameters.  See	above.

       Most of the time, ARG0 and ARG1 will be the same.  Exceptions are if
       you are monitoring "*" or if you	supplied a full	IKC event specifier to
       IKC/monitor rather then just a plain kernel name.

   Short note about monitoring all kernels with	"*"
       There are 2 reasons circonstances in which you will be monitoring all
       remote kernels :	names known in advance and names unknown in advance.

       If you know kernel names	in advance, you	might be better	off monitoring
       a given kernel name.  However, you might	prefer doing a case-like
       compare on ARG1 (with regexes, say).  This would	be useful for
       clustering, where various redundant kernels could follow	a naming
       convention like [application]-[host], so	you could compare "ARG1" with
       "/^credit-/" to find out	if you want to set up specific things for that

       Not knowing the name of a kernel	in advance, you	could be doing some
       sort of autodiscovery or	maybe just monitoring for debuging, logging or
       book-keeping purposes.  You obviously don't want	to do autodiscovery
       for every alias of every	kernel,	only for the "cannonical name",	hence
       the need	for ARG2.

   Short note the second
       You are more then allowed (in fact, you are encouraged) to use the same
       callback	states when monitoring multiple	kernels.  In this case,	you
       will find ARG0 useful for telling them apart.

	   $kernel->post('IKC',	'monitor', '*',
			    data=>'magic box'});

       Now remote_{register,unregister,subscribe,unsubscribe} is called	for
       any remote kernel.

	   $kernel->post('IKC',	'monitor', 'Pulse', {register=>'pulse_connected'});

       "pulse_connected" will be called	in current session when	you succeed in
       connecting to a kernel called 'Pulse'.

	   $kernel->post('IKC',	'monitor', '*');

       Session is no longer monitoring all kernels, only 'Pulse'.

	   $kernel->post('IKC',	'monitor', 'Pulse', {});

       Now we aren't even interested in	'Pulse';

       Previous	versions of IKC	did not	adequately allow you to	control	a
       connection.  With 0.2400	we added a much	needed feature.

       Each connection to a remote kernel is handled by	a channel session.
       You find	out the	session's ID by	monitoring for "channel" operations.
       You may close a channel and the corresponding connection	to the remote
       kernel by sending it a "shutdown" event.

	   sub _start {
	       # set up	the monitor
	       $poe_kernel->call( IKC => monitor => '*'	=> { channel =>	'channel' } );

	   sub channel {
	       my( $self, $rid,	$rkernel, $real, $data,	$op, $channel )	= @_[ OBJECT, ARG0..$#_	];
	       return unless $real;    # only care about the real kernel ID
	       if( $op eq 'ready' ) {  # new channel is	ready
		   $self->{channel}{ $rkernel }	= $channel;
	       elsif( $op eq 'close' ) {   # channel is	gone
		   delete $self->{channel}{ $rkernel };

	   # this an event posted from your controler logic
	   sub close_channel {
	       my( $self, $rkernel ) = @_[ OBJECT, ARG0	];
	       # tell the channel to close
	       $poe_kernel->post( $self->{channel}{ $rkernel } => 'shutdown' );

       Previous	versions of IKC	did not	adequately allow you to	monitor	for
       errors on a connection.	With 0.2400 we started monitoring errors.

       There are 2 step	during which you can have errors: when opening the
       connection and during message exchange.	These 2	steps are handled

       You use "on_error" in POE::Component::IKC::Client and "on_error"	in
       POE::Component::IKC::Server to receive errors while a connection	is
       being opened.  Note that	this includes the initial IKC handshake.

	   sub on_error
	       my( $op,	$errnum, $errstr ) = @_;
	       # Handle	this like you would any	POE socket error
	       # But remember you can't	rely on	your session being active

       You use "monitor" on error to receive errors during message exchange.
       ARG3 is the name	of the operation.  ARG4	is the error message.  Current
       operations are:

	   Remote kernel was unable to parse a request that was	sent from the
	   local kernel.

	   Remote kernel has not published an event that was sent from the
	   local kernel.

	   Remote kernel could not find	a session that could handle the

	   Remote kernel had an	error when it tried to invoke the request
	   handler.  Please note this will not catch errors in the request
	   handler, but	only errors in the thunk.

	   These 4 operations are the local equivalent of the previous 4.
	   They	are intented for logging.  In general no actions are required.

	   Note	that 'local' and 'remote' refer	to where the operation
	   happened, not where the request originated.	As an example, kernel
	   A sends a poe://B/foo/bar request to	kernel B.  Kernel B has	not
	   published that event.  Monitors on kernel A will see	remote-check.
	   Monitors on kernel B	will see local-check.

	   Receive channel errors during message exchange.   Channel errors
	   are equivalent to POE wheel errors.	The message will be "[$errnum]

	   Failure to subscribe	to a remote session.

	   POE::Component::IKC::Server failed to fork.

	   Error when trying to	find a remote kernel or	session.

       Example monitor for error events:

	   sub monitor_error
	       my( $self, $rid,	$kernel, $real,	$data, $op, $message ) =
		       @_[ OBJECT, ARG0	... $#_	];
	       if( $op =~ /^channel-/ and $message =~ /\[(\d+)\] (.*)/ ) {
		   return unless $real;
		   my( $errnum,	$errstr	) = ( $1, $2 );
		   if( $op eq 'channel-read' and $errnum == 0 )	{
		       warn "Connection	closed";
	       warn "Error during $op: $message";

       In particular, you will note we don't do	anything when we detect	the
       channel closed.	Instead, it is recommended to attempt reconnection in
       the "unregister"	event.

       DEPRECATED.  Please use


       Event handlers invoked via IKC will have	a proxy	SENDER session.	You
       may use it to post back to the remote session.

	   $poe_kernel->post( $_[SENDER], 'response', @args );

       Normally	this proxy session is available	during the invocation of the
       event handler.  You may claim it	for longer by setting an external

	   $heap->{remote} = $_[SENDER]->ID;
	   $poe_kernel->refcount_increment( $heap->{remote}, 'MINE' );

       POE::Component::IKC will	detect this and	create a new proxy session for
       future calls.  It will then be UP TO YOU	to free	the session:

	   $poe_kernel->refcount_decrement( $heap->{remote}, 'MINE' );

       Note that you will have to publish any events that will be posted back.

       Sending session references and coderefs to a foreign kernel is a	bad
       idea.  At some point it would be	desirable to recurse through the
       paramerters and and turn	any session references into state specifiers.

       The "rsvp" state	in call	is a bit problematic.  IKC allows it to	be
       posted to once, but doesn't check to see	if the foreign kernel is the
       right one.

       "retract" does not currently tell foreign kernels that have subscribed
       to a session/state about	the retraction.

       "call()"ing a state in a	proxied	foreign	session	doesn't	work, for
       obvious reasons.

       Philip Gwyn, <perl-ikc at>

       Copyright 1999-2014 by Philip Gwyn.  All	rights reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       See <>

       POE, POE::Component::IKC::Server, POE::Component::IKC::Client,
       POE::Component::IKC::ClientLite,	POE::Component::IKC::Channel,
       POE::Component::IKC::Proxy, POE::Component::IKC::Freezer,

perl v5.32.0			  2014-07-07		     IKC::Responder(3)


Want to link to this manual page? Use this URL:

home | help