… | |
… | |
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 | |
45 | This module (-family) implements a simple message passing framework. |
59 | This module (-family) implements a simple message passing framework. |
46 | |
60 | |
47 | Despite its simplicity, you can securely message other processes running |
61 | Despite its simplicity, you can securely message other processes running |
… | |
… | |
50 | For an introduction to this module family, see the L<AnyEvent::MP::Intro> |
64 | For an introduction to this module family, see the L<AnyEvent::MP::Intro> |
51 | manual page. |
65 | manual page. |
52 | |
66 | |
53 | At the moment, this module family is severly broken and underdocumented, |
67 | At the moment, this module family is severly broken and underdocumented, |
54 | so do not use. This was uploaded mainly to reserve the CPAN namespace - |
68 | so do not use. This was uploaded mainly to reserve the CPAN namespace - |
55 | stay tuned! The basic API should be finished, however. |
69 | stay 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 | |
108 | package AnyEvent::MP; |
122 | package AnyEvent::MP; |
109 | |
123 | |
110 | use AnyEvent::MP::Base; |
124 | use AnyEvent::MP::Kernel; |
111 | |
125 | |
112 | use common::sense; |
126 | use common::sense; |
113 | |
127 | |
114 | use Carp (); |
128 | use Carp (); |
115 | |
129 | |
116 | use AE (); |
130 | use AE (); |
117 | |
131 | |
118 | use base "Exporter"; |
132 | use base "Exporter"; |
119 | |
133 | |
120 | our $VERSION = $AnyEvent::MP::Base::VERSION; |
134 | our $VERSION = $AnyEvent::MP::Kernel::VERSION; |
121 | |
135 | |
122 | our @EXPORT = qw( |
136 | our @EXPORT = qw( |
123 | NODE $NODE *SELF node_of _any_ |
137 | NODE $NODE *SELF node_of _any_ |
124 | resolve_node initialise_node |
138 | resolve_node initialise_node |
125 | snd rcv mon kil reg psub spawn |
139 | snd rcv mon kil reg psub spawn |
… | |
… | |
846 | This also saves round-trips and avoids sending messages to the wrong port |
860 | This also saves round-trips and avoids sending messages to the wrong port |
847 | (hard to do in Erlang). |
861 | (hard to do in Erlang). |
848 | |
862 | |
849 | =back |
863 | =back |
850 | |
864 | |
|
|
865 | =head1 RATIONALE |
|
|
866 | |
|
|
867 | =over 4 |
|
|
868 | |
|
|
869 | =item Why strings for ports and noderefs, why not objects? |
|
|
870 | |
|
|
871 | We considered "objects", but found that the actual number of methods |
|
|
872 | thatc an be called are very low. Since port IDs and noderefs travel over |
|
|
873 | the network frequently, the serialising/deserialising would add lots of |
|
|
874 | overhead, as well as having to keep a proxy object. |
|
|
875 | |
|
|
876 | Strings can easily be printed, easily serialised etc. and need no special |
|
|
877 | procedures to be "valid". |
|
|
878 | |
|
|
879 | And a a miniport consists of a single closure stored in a global hash - it |
|
|
880 | can't become much cheaper. |
|
|
881 | |
|
|
882 | =item Why favour JSON, why not real serialising format such as Storable? |
|
|
883 | |
|
|
884 | In fact, any AnyEvent::MP node will happily accept Storable as framing |
|
|
885 | format, but currently there is no way to make a node use Storable by |
|
|
886 | default. |
|
|
887 | |
|
|
888 | The default framing protocol is JSON because a) JSON::XS is many times |
|
|
889 | faster for small messages and b) most importantly, after years of |
|
|
890 | experience we found that object serialisation is causing more problems |
|
|
891 | than it gains: Just like function calls, objects simply do not travel |
|
|
892 | easily over the network, mostly because they will always be a copy, so you |
|
|
893 | always have to re-think your design. |
|
|
894 | |
|
|
895 | Keeping your messages simple, concentrating on data structures rather than |
|
|
896 | objects, will keep your messages clean, tidy and efficient. |
|
|
897 | |
|
|
898 | =back |
|
|
899 | |
851 | =head1 SEE ALSO |
900 | =head1 SEE ALSO |
852 | |
901 | |
853 | L<AnyEvent>. |
902 | L<AnyEvent>. |
854 | |
903 | |
855 | =head1 AUTHOR |
904 | =head1 AUTHOR |