ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP.pm
(Generate patch)

Comparing AnyEvent-MP/MP.pm (file contents):
Revision 1.40 by root, Sat Aug 8 00:22:16 2009 UTC vs.
Revision 1.48 by root, Thu Aug 13 02:59:42 2009 UTC

9 $NODE # contains this node's noderef 9 $NODE # contains this node's noderef
10 NODE # returns this node's noderef 10 NODE # returns this node's noderef
11 NODE $port # returns the noderef of the port 11 NODE $port # returns the noderef of the port
12 12
13 $SELF # receiving/own port id in rcv callbacks 13 $SELF # receiving/own port id in rcv callbacks
14
15 # initialise the node so it can send/receive messages
16 initialise_node; # -OR-
17 initialise_node "localhost:4040"; # -OR-
18 initialise_node "slave/", "localhost:4040"
14 19
15 # ports are message endpoints 20 # ports are message endpoints
16 21
17 # sending messages 22 # sending messages
18 snd $port, type => data...; 23 snd $port, type => data...;
19 snd $port, @msg; 24 snd $port, @msg;
20 snd @msg_with_first_element_being_a_port; 25 snd @msg_with_first_element_being_a_port;
21 26
22 # miniports 27 # creating/using miniports
23 my $miniport = port { my @msg = @_; 0 }; 28 my $miniport = port { my @msg = @_; 0 };
24 29
25 # full ports 30 # creating/using full ports
26 my $port = port; 31 my $port = port;
27 rcv $port, smartmatch => $cb->(@msg); 32 rcv $port, smartmatch => $cb->(@msg);
28 rcv $port, ping => sub { snd $_[0], "pong"; 0 }; 33 rcv $port, ping => sub { snd $_[0], "pong"; 0 };
29 rcv $port, pong => sub { warn "pong received\n"; 0 }; 34 rcv $port, pong => sub { warn "pong received\n"; 0 };
30 35
31 # remote ports
32 my $port = spawn $node, $initfunc, @initdata;
33
34 # more, smarter, matches (_any_ is exported by this module) 36 # more, smarter, matches (_any_ is exported by this module)
35 rcv $port, [child_died => $pid] => sub { ... 37 rcv $port, [child_died => $pid] => sub { ...
36 rcv $port, [_any_, _any_, 3] => sub { .. $_[2] is 3 38 rcv $port, [_any_, _any_, 3] => sub { .. $_[2] is 3
39
40 # create a port on another node
41 my $port = spawn $node, $initfunc, @initdata;
37 42
38 # monitoring 43 # monitoring
39 mon $port, $cb->(@msg) # callback is invoked on death 44 mon $port, $cb->(@msg) # callback is invoked on death
40 mon $port, $otherport # kill otherport on abnormal death 45 mon $port, $otherport # kill otherport on abnormal death
41 mon $port, $otherport, @msg # send message on death 46 mon $port, $otherport, @msg # send message on death
42 47
48=head1 CURRENT STATUS
49
50 AnyEvent::MP - stable API, should work
51 AnyEvent::MP::Intro - outdated
52 AnyEvent::MP::Kernel - WIP
53 AnyEvent::MP::Transport - mostly stable
54
55 stay tuned.
56
43=head1 DESCRIPTION 57=head1 DESCRIPTION
44 58
45This module (-family) implements a simple message passing framework. 59This module (-family) implements a simple message passing framework.
46 60
47Despite its simplicity, you can securely message other processes running 61Despite its simplicity, you can securely message other processes running
50For an introduction to this module family, see the L<AnyEvent::MP::Intro> 64For an introduction to this module family, see the L<AnyEvent::MP::Intro>
51manual page. 65manual page.
52 66
53At the moment, this module family is severly broken and underdocumented, 67At the moment, this module family is severly broken and underdocumented,
54so do not use. This was uploaded mainly to reserve the CPAN namespace - 68so do not use. This was uploaded mainly to reserve the CPAN namespace -
55stay tuned! The basic API should be finished, however. 69stay tuned!
56 70
57=head1 CONCEPTS 71=head1 CONCEPTS
58 72
59=over 4 73=over 4
60 74
105 119
106=cut 120=cut
107 121
108package AnyEvent::MP; 122package AnyEvent::MP;
109 123
110use AnyEvent::MP::Base; 124use AnyEvent::MP::Kernel;
111 125
112use common::sense; 126use common::sense;
113 127
114use Carp (); 128use Carp ();
115 129
116use AE (); 130use AE ();
117 131
118use base "Exporter"; 132use base "Exporter";
119 133
120our $VERSION = '0.1'; 134our $VERSION = $AnyEvent::MP::Kernel::VERSION;
135
121our @EXPORT = qw( 136our @EXPORT = qw(
122 NODE $NODE *SELF node_of _any_ 137 NODE $NODE *SELF node_of _any_
123 resolve_node initialise_node 138 resolve_node initialise_node
124 snd rcv mon kil reg psub spawn 139 snd rcv mon kil reg psub spawn
125 port 140 port
501 516
502=item $guard = mon $port 517=item $guard = mon $port
503 518
504=item $guard = mon $port, $rcvport, @msg 519=item $guard = mon $port, $rcvport, @msg
505 520
506Monitor the given port and do something when the port is killed, and 521Monitor the given port and do something when the port is killed or
507optionally return a guard that can be used to stop monitoring again. 522messages to it were lost, and optionally return a guard that can be used
523to stop monitoring again.
524
525C<mon> effectively guarantees that, in the absence of hardware failures,
526that after starting the monitor, either all messages sent to the port
527will arrive, or the monitoring action will be invoked after possible
528message loss has been detected. No messages will be lost "in between"
529(after the first lost message no further messages will be received by the
530port). After the monitoring action was invoked, further messages might get
531delivered again.
508 532
509In the first form (callback), the callback is simply called with any 533In the first form (callback), the callback is simply called with any
510number of C<@reason> elements (no @reason means that the port was deleted 534number of C<@reason> elements (no @reason means that the port was deleted
511"normally"). Note also that I<< the callback B<must> never die >>, so use 535"normally"). Note also that I<< the callback B<must> never die >>, so use
512C<eval> if unsure. 536C<eval> if unsure.
513 537
514In the second form (another port given), the other port (C<$rcvport) 538In the second form (another port given), the other port (C<$rcvport>)
515will be C<kil>'ed with C<@reason>, iff a @reason was specified, i.e. on 539will be C<kil>'ed with C<@reason>, iff a @reason was specified, i.e. on
516"normal" kils nothing happens, while under all other conditions, the other 540"normal" kils nothing happens, while under all other conditions, the other
517port is killed with the same reason. 541port is killed with the same reason.
518 542
519The third form (kill self) is the same as the second form, except that 543The third form (kill self) is the same as the second form, except that
546sub mon { 570sub mon {
547 my ($noderef, $port) = split /#/, shift, 2; 571 my ($noderef, $port) = split /#/, shift, 2;
548 572
549 my $node = $NODE{$noderef} || add_node $noderef; 573 my $node = $NODE{$noderef} || add_node $noderef;
550 574
551 my $cb = @_ ? $_[0] : $SELF || Carp::croak 'mon: called with one argument only, but $SELF not set,'; 575 my $cb = @_ ? shift : $SELF || Carp::croak 'mon: called with one argument only, but $SELF not set,';
552 576
553 unless (ref $cb) { 577 unless (ref $cb) {
554 if (@_) { 578 if (@_) {
555 # send a kill info message 579 # send a kill info message
556 my (@msg) = @_; 580 my (@msg) = ($cb, @_);
557 $cb = sub { snd @msg, @_ }; 581 $cb = sub { snd @msg, @_ };
558 } else { 582 } else {
559 # simply kill other port 583 # simply kill other port
560 my $port = $cb; 584 my $port = $cb;
561 $cb = sub { kil $port, @_ if @_ }; 585 $cb = sub { kil $port, @_ if @_ };
836This also saves round-trips and avoids sending messages to the wrong port 860This also saves round-trips and avoids sending messages to the wrong port
837(hard to do in Erlang). 861(hard to do in Erlang).
838 862
839=back 863=back
840 864
865=head1 RATIONALE
866
867=over 4
868
869=item Why strings for ports and noderefs, why not objects?
870
871We considered "objects", but found that the actual number of methods
872thatc an be called are very low. Since port IDs and noderefs travel over
873the network frequently, the serialising/deserialising would add lots of
874overhead, as well as having to keep a proxy object.
875
876Strings can easily be printed, easily serialised etc. and need no special
877procedures to be "valid".
878
879And a a miniport consists of a single closure stored in a global hash - it
880can't become much cheaper.
881
882=item Why favour JSON, why not real serialising format such as Storable?
883
884In fact, any AnyEvent::MP node will happily accept Storable as framing
885format, but currently there is no way to make a node use Storable by
886default.
887
888The default framing protocol is JSON because a) JSON::XS is many times
889faster for small messages and b) most importantly, after years of
890experience we found that object serialisation is causing more problems
891than it gains: Just like function calls, objects simply do not travel
892easily over the network, mostly because they will always be a copy, so you
893always have to re-think your design.
894
895Keeping your messages simple, concentrating on data structures rather than
896objects, will keep your messages clean, tidy and efficient.
897
898=back
899
841=head1 SEE ALSO 900=head1 SEE ALSO
842 901
843L<AnyEvent>. 902L<AnyEvent>.
844 903
845=head1 AUTHOR 904=head1 AUTHOR

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines