AnyEvent-MP
view release on metacpan or search on metacpan
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.
}
}
}
$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.
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.
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 )