… | |
… | |
13 | |
13 | |
14 | write_log => 1251555874, "action was successful.\n" |
14 | write_log => 1251555874, "action was successful.\n" |
15 | 123, ["a", "b", "c"], { foo => "bar" } |
15 | 123, ["a", "b", "c"], { foo => "bar" } |
16 | |
16 | |
17 | When using L<AnyEvent::MP> it is customary to use a descriptive string as |
17 | When using L<AnyEvent::MP> it is customary to use a descriptive string as |
18 | first element of a message, that indicates the type of the message. This |
18 | first element of a message that indicates the type of the message. This |
19 | element is called a I<tag> in L<AnyEvent::MP>, as some API functions |
19 | element is called a I<tag> in L<AnyEvent::MP>, as some API functions |
20 | (C<rcv>) support matching it directly. |
20 | (C<rcv>) support matching it directly. |
21 | |
21 | |
22 | Supposedly you want to send a ping message with your current time to |
22 | Supposedly you want to send a ping message with your current time to |
23 | somewhere, this is how such a message might look like (in Perl syntax): |
23 | somewhere, this is how such a message might look like (in Perl syntax): |
… | |
… | |
60 | |
60 | |
61 | The strings for the I<port IDs> here are just for illustrative |
61 | The strings for the I<port IDs> here are just for illustrative |
62 | purposes: Even though I<ports> in L<AnyEvent::MP> are also identified by |
62 | purposes: Even though I<ports> in L<AnyEvent::MP> are also identified by |
63 | strings, they can't be chosen manually and are assigned by the system |
63 | strings, they can't be chosen manually and are assigned by the system |
64 | dynamically. These I<port IDs> are unique within a network and can also be |
64 | dynamically. These I<port IDs> are unique within a network and can also be |
65 | used to identify senders or as message tags for instance. |
65 | used to identify senders, or even as message tags for instance. |
66 | |
66 | |
67 | The next sections will explain the API of L<AnyEvent::MP> by going through |
67 | The next sections will explain the API of L<AnyEvent::MP> by going through |
68 | a few simple examples. Later some more complex idioms are introduced, |
68 | a few simple examples. Later some more complex idioms are introduced, |
69 | which are hopefully useful to solve some real world problems. |
69 | which are hopefully useful to solve some real world problems. |
70 | |
70 | |
71 | =head2 Passing Your First Message |
71 | =head2 Passing Your First Message |
72 | |
72 | |
73 | As a start lets have a look at the messaging API. The following example |
73 | For starters, let's have a look at the messaging API. The following |
74 | is just a demo to show the basic elements of message passing with |
74 | example is just a demo to show the basic elements of message passing with |
75 | L<AnyEvent::MP>. |
75 | L<AnyEvent::MP>. |
76 | |
76 | |
77 | The example should print: C<Ending with: 123>, in a rather complicated |
77 | The example should print: C<Ending with: 123>, in a rather complicated |
78 | way, by passing some message to a port. |
78 | way, by passing some message to a port. |
79 | |
79 | |
… | |
… | |
92 | snd $port, test => 123; |
92 | snd $port, test => 123; |
93 | |
93 | |
94 | print "Ending with: " . $end_cv->recv . "\n"; |
94 | print "Ending with: " . $end_cv->recv . "\n"; |
95 | |
95 | |
96 | It already uses most of the essential functions inside |
96 | It already uses most of the essential functions inside |
97 | L<AnyEvent::MP>: First there is the C<port> function which will create a |
97 | L<AnyEvent::MP>: First there is the C<port> function which creates a |
98 | I<port> and will return it's I<port ID>, a simple string. |
98 | I<port> and will return it's I<port ID>, a simple string. |
99 | |
99 | |
100 | This I<port ID> can be used to send messages to the port and install |
100 | This I<port ID> can be used to send messages to the port and install |
101 | handlers to receive messages on the port. Since it is a simple string |
101 | handlers to receive messages on the port. Since it is a simple string |
102 | it can be safely passed to other I<nodes> in the network when you want |
102 | it can be safely passed to other I<nodes> in the network when you want |
… | |
… | |
179 | that you can set. The first, C<PERL_ANYEVENT_MP_WARNLEVEL> sets the |
179 | that you can set. The first, C<PERL_ANYEVENT_MP_WARNLEVEL> sets the |
180 | logging level. The default is C<5>, which means nothing much is |
180 | logging level. The default is C<5>, which means nothing much is |
181 | printed. You can increase it to C<8> or C<9> to get more verbose |
181 | printed. You can increase it to C<8> or C<9> to get more verbose |
182 | output. This is example output when starting a node: |
182 | output. This is example output when starting a node: |
183 | |
183 | |
184 | 2009-08-31 19:51:50 <8> node anon/5RloFvvYL8jfSScXNL8EpX starting up. |
184 | 2012-03-04 19:41:10 <8> node cerebro starting up. |
185 | 2009-08-31 19:51:50 <7> starting global service. |
185 | 2012-03-04 19:41:10 <8> node listens on [10.0.0.1:4040]. |
|
|
186 | 2012-03-04 19:41:10 <9> trying connect to seed node 10.0.0.19:4040. |
186 | 2009-08-31 19:51:50 <9> 10.0.0.17:4040 connected as ruth |
187 | 2012-03-04 19:41:10 <9> 10.0.0.19:4040 connected as rain |
187 | 2009-08-31 19:51:50 <7> ruth is up () |
188 | 2012-03-04 19:41:10 <7> rain is up () |
188 | 2009-08-31 19:51:50 <9> ruth told us it knows about {"doom":["10.0.0.5:45143"],"rain":["10.0.0.19:4040"],"anon/4SYrtJ3ft5l1C16w2hto3t":["10.0.0.1:45920","[2002:58c6:438b:20:21d:60ff:fee8:6e36]:35788","[fd00::a00:1]:37104"],"frank":["10.0.0.18:4040"]}. |
|
|
189 | 2009-08-31 19:51:50 <9> connecting to doom with [10.0.0.5:45143] |
|
|
190 | 2009-08-31 19:51:50 <9> connecting to anon/4SYrtJ3ft5l1C16w2hto3t with [10.0.0.1:45920 [2002:58c6:438b:20:21d:60ff:fee8:6e36]:35788 [fd00::a00:1]:37104] |
|
|
191 | 2009-08-31 19:51:50 <9> ruth told us its addresses (10.0.0.17:4040). |
|
|
192 | |
189 | |
193 | A lot of info, but at least you can see that it does something. |
190 | A lot of info, but at least you can see that it does something. |
194 | |
191 | |
195 | The other environment variable that can be useful is |
192 | The other environment variable that can be useful is |
196 | C<PERL_ANYEVENT_MP_TRACE>, which, when set to a true value, will cause |
193 | C<PERL_ANYEVENT_MP_TRACE>, which, when set to a true value, will cause |
197 | most messages that are sent or received to be printed. In the above |
194 | most messages that are sent or received to be printed. For example, F<aemp |
198 | example you would see something like: |
195 | restart rijk> might output these message exchanges: |
199 | |
196 | |
200 | SND ruth <- ["addr",["10.0.0.1:49358","[2002:58c6:438b:20:21d:60ff:fee8:6e36]:58884","[fd00::a00:1]:45006"]] |
197 | SND rijk <- [null,"eval","AnyEvent::Watchdog::Util::restart; ()","aemp/cerebro/z4kUPp2JT4#b"] |
201 | RCV ruth -> ["","AnyEvent::MP::_spawn","20QA7cWubCLTWUhFgBKOx2.x","AnyEvent::MP::Global::connect",0,"ruth"] |
198 | SND rain <- [null,"g_slave",{"'l":{"aemp/cerebro/z4kUPp2JT4":["10.0.0.1:48168"]}}] |
202 | RCV ruth -> ["","mon1","20QA7cWubCLTWUhFgBKOx2.x"] |
199 | SND rain <- [null,"g_find","rijk"] |
203 | RCV ruth -> ["20QA7cWubCLTWUhFgBKOx2.x","addr",["10.0.0.17:4040"]] |
200 | RCV rain -> ["","g_found","rijk",["10.0.0.23:4040"]] |
204 | RCV ruth -> ["20QA7cWubCLTWUhFgBKOx2.x","nodes",{"doom":["10.0.0.5:45143"],"rain":["10.0.0.19:4040"],"anon/4SYrtJ3ft5l1C16w2hto3t":["10.0.0.1:45920","[2002:58c6:438b:20:21d:60ff:fee8:6e36]:35788","[fd00::a00:1]:37104"],"frank":["10.0.0.18:4040"]}] |
201 | RCV rijk -> ["b",""] |
205 | |
202 | |
206 | =head1 PART 1: Passing Messages Between Processes |
203 | =head1 PART 1: Passing Messages Between Processes |
207 | |
204 | |
208 | =head2 The Receiver |
205 | =head2 The Receiver |
209 | |
206 | |