AnyEvent-MP

 view release on metacpan or  search on metacpan

MP.pm  view on Meta::CPAN

The type of data you can transfer depends on the transport protocol: when
JSON is used, then only strings, numbers and arrays and hashes consisting
of those are allowed (no objects). When Storable is used, then anything
that Storable can serialise and deserialise is allowed, and for the local
node, anything can be passed. Best rely only on the common denominator of
these.

=item $local_port = port

Create a new local port object and returns its port ID. Initially it has
no callbacks set and will throw an error when it receives messages.

=item $local_port = port { my @msg = @_ }

Creates a new local port, and returns its ID. Semantically the same as
creating a port and calling C<rcv $port, $callback> on it.

The block will be called for every message received on the port, with the
global variable C<$SELF> set to the port ID. Runtime errors will cause the
port to be C<kil>ed. The message will be passed as-is, no extra argument
(i.e. no port ID) will be passed to the callback.

MP.pm  view on Meta::CPAN

         }
      }
   }

   $port
}

=item peval $port, $coderef[, @args]

Evaluates the given C<$codref> within the context of C<$port>, that is,
when the code throws an exception the C<$port> will be killed.

Any remaining args will be passed to the callback. Any return values will
be returned to the caller.

This is useful when you temporarily want to execute code in the context of
a port.

Example: create a port and run some initialisation code in it's context.

   my $port = port { ... };

MP/Intro.pod  view on Meta::CPAN


AnyEvent::MP supports this by catching exceptions and network problems,
and notifying interested parties of these.

=head2 Exceptions, Port Context, Network Errors and Monitors

=head3 Exceptions

Exceptions are handled on a per-port basis: all receive callbacks are
executed in a special context, the so-called I<port-context>: code
that throws an otherwise uncaught exception will cause the port to be
C<kil>led. Killed ports are destroyed automatically (killing ports is
actually the only way to free ports).

Ports can be monitored, even from a different node and host, and when a
port is killed, any entity monitoring it will be notified.

Here is a simple example:

  use AnyEvent::MP;

MP/Intro.pod  view on Meta::CPAN

  # monitor it
  mon $port, sub {
     warn "$port was killed (with reason @_)";
  };

  # now send it some message, causing it to die:
  snd $port;

  AnyEvent->condvar->recv;

It first creates a port whose only action is to throw an exception,
and the monitors it with the C<mon> function. Afterwards it sends it a
message, causing it to die and call the monitoring callback:

   anon/6WmIpj.a was killed (with reason die oops at xxx line 5.) at xxx line 9.

The callback was actually passed two arguments: C<die>, to indicate it
did throw an I<exception> as opposed to, say, a network error, and the
exception message itself.

What happens when a port is killed before we have a chance to monitor
it? Granted, this is highly unlikely in our example, but when you program
in a network this can easily happen due to races between nodes.

  use AnyEvent::MP;

  my $port = port { die "oops" };

MP/Intro.pod  view on Meta::CPAN

   mon $port, $SELF;

This basically means "monitor $port and kill me when it crashes" - and
the thing is, a "normal" kill does not count as a crash. This way you can
easily link ports together and make them crash together on errors, while
allowing you to remove a port silently when it has done it's job properly.

=head3 Port Context

Code runs in the so-called "port context". That means C<$SELF> contains
its own port ID and exceptions that the code throws will be caught.

Since AnyEvent::MP is event-based, it is not uncommon to register
callbacks from within C<rcv> handlers. As example, assume that the
following port receive handler wants to C<die> a second later, using
C<after>:

  my $port = port {
     after 1, sub { die "oops" };
  };

MP/Intro.pod  view on Meta::CPAN

arguments to it, and - most importantly - executes the function within
the context of the new port, so it can be manipulated by referring to
C<$SELF>. The init function can reside in a module (actually it normally
I<should> reside in a module) - AnyEvent::MP will automatically load the
module if the function isn't defined.

The C<spawn> function returns immediately, which means you can instantly
send messages to the port, long before the remote node has even heard
of our request to create a port on it. In fact, the remote node might
not even be running. Despite these troubling facts, everything should
work just fine: if the node isn't running (or the init function throws an
exception), then the monitor will trigger because the port doesn't exist.

If the spawn message gets delivered, but the monitoring message is not
because of network problems (extremely unlikely, but monitoring, after
all, is implemented by passing a message, and messages can get lost), then
this connection loss will eventually trigger the monitoring action. On the
remote node (which in return monitors the client) the port will also be
cleaned up on connection loss. When the remote node comes up again and our
monitoring message can be delivered, it will instantly fail because the
port has been cleaned up in the meantime.

README  view on Meta::CPAN


        The type of data you can transfer depends on the transport protocol:
        when JSON is used, then only strings, numbers and arrays and hashes
        consisting of those are allowed (no objects). When Storable is used,
        then anything that Storable can serialise and deserialise is
        allowed, and for the local node, anything can be passed. Best rely
        only on the common denominator of these.

    $local_port = port
        Create a new local port object and returns its port ID. Initially it
        has no callbacks set and will throw an error when it receives
        messages.

    $local_port = port { my @msg = @_ }
        Creates a new local port, and returns its ID. Semantically the same
        as creating a port and calling "rcv $port, $callback" on it.

        The block will be called for every message received on the port,
        with the global variable $SELF set to the port ID. Runtime errors
        will cause the port to be "kil"ed. The message will be passed as-is,
        no extra argument (i.e. no port ID) will be passed to the callback.

README  view on Meta::CPAN

        received.

           rcv $port, $otherport => sub {
              my @reply = @_;

              rcv $SELF, $otherport;
           };

    peval $port, $coderef[, @args]
        Evaluates the given $codref within the context of $port, that is,
        when the code throws an exception the $port will be killed.

        Any remaining args will be passed to the callback. Any return values
        will be returned to the caller.

        This is useful when you temporarily want to execute code in the
        context of a port.

        Example: create a port and run some initialisation code in it's
        context.



( run in 0.425 second using v1.01-cache-2.11-cpan-496ff517765 )