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

Comparing AnyEvent-MP/MP/Intro.pod (file contents):
Revision 1.50 by root, Fri Mar 9 19:07:53 2012 UTC vs.
Revision 1.51 by root, Wed Mar 21 00:14:25 2012 UTC

222 print "Received data: " . $data . "\n"; 222 print "Received data: " . $data . "\n";
223 }; 223 };
224 224
225 AnyEvent->condvar->recv; 225 AnyEvent->condvar->recv;
226 226
227=head3 AnyEvent::MP::Global
228
229Now, that wasn't too bad, was it? OK, let's step through the new functions 227Now, that wasn't too bad, was it? OK, let's go through the new functions
230that have been used. 228that have been used.
231 229
232=head3 C<configure> and Joining and Maintaining the Network 230=head3 C<configure> and Joining and Maintaining the Network
233 231
234First let's have a look at C<configure>: 232First let's have a look at C<configure>:
317 315
318 my $port = port; 316 my $port = port;
319 db_set eg_receivers => $port; 317 db_set eg_receivers => $port;
320 318
321The C<port> function has already been discussed. It simply creates a new 319The C<port> function has already been discussed. It simply creates a new
322I<port> and returns the I<port ID>. The C<db_reg> function, however, is 320I<port> and returns the I<port ID>. The C<db_set> function, however, is
323new: The first argument is the name of a I<database family> and the second 321new: The first argument is the name of a I<database family> and the second
324argument is the name of a I<subkey> within that family. The third argument 322argument is the name of a I<subkey> within that family. The third argument
325would be the I<value> to be associated with the family and subkey, but, 323would be the I<value> to be associated with the family and subkey, but,
326since it is missing, it will simply be C<undef>. 324since it is missing, it will simply be C<undef>.
327 325
328OK, what's this weird talk about families you wonder - AnyEvent::MP comes 326What is a "family" you wonder? Well, AnyEvent::MP comes with a distributed
329with a distributed database. This database runs on so-called "global" 327database. This database runs on so-called "global" nodes, which usually
330nodes, which usually are the seed nodes of your network. The database 328are the seed nodes of your network. The database structure is "simply" a
331structure is "simply" a hash of hashes of values. 329hash of hashes of values.
332 330
333In other words, if the database were stored in C<%DB>, then the C<db_set> 331To illustrate this with Perl syntax, assume the database was stored in
334function more or less would do this: 332C<%DB>, then the C<db_set> function more or less would do this:
335 333
336 $DB{eg_receivers}{$port} = undef; 334 $DB{eg_receivers}{$port} = undef;
337 335
338So the ominous "family" selects a hash in the database, and the "subkey" 336So the ominous "family" selects a hash in the database, and the "subkey"
339is simply the key in this hash. And C<db_set> very much works like an 337is simply the key in this hash - C<db_set> very much works like this
340assignment. 338assignment.
341 339
342The family namespace is shared by all nodes in a network, so the names 340The family namespace is shared by all nodes in a network, so the names
343should be reasonably unique, for example, they could start with the name 341should be reasonably unique, for example, they could start with the name
344of your module, or the name of the program, using your port name or node 342of your module, or the name of the program, using your port name or node
404different computers. 402different computers.
405 403
406Each time you start the sender, it will send a message to all receivers it 404Each time you start the sender, it will send a message to all receivers it
407finds (you have to interrupt it manually afterwards). 405finds (you have to interrupt it manually afterwards).
408 406
409Additional things you could try include using C<PERL_ANYEVENT_MP_TRACE=1> 407Additional experiments you could try include using
410to see which messages are exchanged, or starting the sender first and see 408C<PERL_ANYEVENT_MP_TRACE=1> to see which messages are exchanged, or
411how long it takes it to find the receiver. 409starting the sender before the receiver and see how long it then takes to
410find the receiver.
412 411
413=head3 Splitting Network Configuration and Application Code 412=head3 Splitting Network Configuration and Application Code
414 413
415OK, so far, this works reasonably. In the real world, however, the person 414OK, so far, this works reasonably. In the real world, however, the person
416configuring your application to run on a specific network (the end user 415configuring your application to run on a specific network (the end user
442We bind the seed node to port 4040 on all interfaces: 441We bind the seed node to port 4040 on all interfaces:
443 442
444 aemp profile seed binds "*:4040" 443 aemp profile seed binds "*:4040"
445 444
446And we configure all nodes to use this as seed node (this only works when 445And we configure all nodes to use this as seed node (this only works when
447running on the same host, for multiple machines you would provide the IP 446running on the same host, for multiple machines you would replace the C<*>
448address or hostname of the node running the seed), by changing the global 447by the IP address or hostname of the node running the seed), by changing
449settings shared between all profiles: 448the global settings shared between all profiles:
450 449
451 aemp seeds "*:4040" 450 aemp seeds "*:4040"
452 451
453Then we run the seed node: 452Then we run the seed node:
454 453
533 warn "$port was killed (with reason @_)"; 532 warn "$port was killed (with reason @_)";
534 }; 533 };
535 534
536 AnyEvent->condvar->recv; 535 AnyEvent->condvar->recv;
537 536
538This time we will get something like: 537This time we will get something else:
539 538
539 2012-03-21 00:50:36 <2> unmonitored local port fADb died with reason: die oops at - line 3.
540 anon/zpX.a was killed (with reason no_such_port cannot monitor nonexistent port) 540 anon/fADb was killed (with reason no_such_port cannot monitor nonexistent port)
541 541
542Since the port was already gone, the kill reason is now C<no_such_port> 542The first line is a warning that is printed when a port dies that isn't
543with some descriptive (we hope) error message. 543being monitored, because that is normally a bug. When later a C<mon> is
544attempted, it is immediately killed, because the port is already gone. The
545kill reason is now C<no_such_port> with some descriptive (we hope) error
546message.
544 547
545In fact, the kill reason is usually some identifier as first argument 548As you probably suspect from these examples, the kill reason is usually
546and a human-readable error message as second argument, but can be about 549some identifier as first argument and a human-readable error message as
547anything (it is simply a list of values you cna choose yourself) or even 550second argument - all kill reasons by AnyEvent::MP itself follow this
551pattern. But the kill reason can be anything: it is simply a list of
552values you can choose yourself. It can even be nothing (an empty list) -
548nothing - which is called a "normal" kill. 553this is called a "normal" kill.
549 554
550You can kill ports manually using the C<kil> function, which will be 555Apart from die'ing, you can kill ports manually using the C<kil>
551treated like an error when any reason is specified: 556function. Using the C<kil> function will be treated like an error when a
557non-empty reason is specified:
552 558
553 kil $port, custom_error => "don't like your steenking face"; 559 kil $port, custom_error => "don't like your steenking face";
554 560
555And a clean kill without any reason arguments: 561And a I<normal> kill without any reason arguments:
556 562
557 kil $port; 563 kil $port;
558 564
559By now you probably wonder what this "normal" kill business is: A common 565By now you probably wonder what this "normal" kill business is: A common
560idiom is to not specify a callback to C<mon>, but another port, such as 566idiom is to not specify a callback to C<mon>, but another port, such as
561C<$SELF>: 567C<$SELF>:
562 568
563 mon $port, $SELF; 569 mon $port, $SELF;
564 570
565This basically means "monitor $port and kill me when it crashes". And a 571This basically means "monitor $port and kill me when it crashes" - and
566"normal" kill does not count as a crash. This way you can easily link 572the thing is, a "normal" kill does not count as a crash. This way you can
567ports together and make them crash together on errors, while allowing you 573easily link ports together and make them crash together on errors, while
568to remove a port silently. 574allowing you to remove a port silently when it has done it's job properly.
569 575
570=head3 Port Context 576=head3 Port Context
571 577
572When code runs in a port context, that means C<$SELF> contains its own 578Code runs in the so-called "port context". That means C<$SELF> contains
573port ID and exceptions that the code throws will be caught. 579its own port ID and exceptions that the code throws will be caught.
574 580
575Since AnyEvent::MP is event-based, it is not uncommon to register 581Since AnyEvent::MP is event-based, it is not uncommon to register
576callbacks from C<rcv> handlers. As example, assume that the port receive 582callbacks from within C<rcv> handlers. As example, assume that the
577handler wants to C<die> a second later, using C<after>: 583following port receive handler wants to C<die> a second later, using
584C<after>:
578 585
579 my $port = port { 586 my $port = port {
580 after 1, sub { die "oops" }; 587 after 1, sub { die "oops" };
581 }; 588 };
582 589
583Then you will find it does not work - when the after callback is executed, 590If you try this out, you would find it does not work - when the C<after>
584it does not run in port context anymore, so exceptions will not be caught. 591callback is executed, it does not run in the port context anymore, so
592exceptions will not be caught.
585 593
586For these cases, AnyEvent::MP exports a special "closure constructor" 594For these cases, AnyEvent::MP exports a special "closure constructor"
587called C<psub>, which works just like perls built-in C<sub>: 595called C<psub>, which works mostly like perl's built-in C<sub>:
588 596
589 my $port = port { 597 my $port = port {
590 after 1, psub { die "oops" }; 598 after 1, psub { die "oops" };
591 }; 599 };
592 600
593C<psub> stores C<$SELF> and returns a code reference. When the code 601C<psub> remembers the port context and returns a code reference. When the
594reference is invoked, it will run the code block within the context of 602code reference is invoked, it will run the code block within the context
595that port, so exception handling once more works as expected. 603that it was created in, so exception handling once more works as expected.
596 604
597There is even a way to temporarily execute code in the context of some 605There is even a way to temporarily execute code in the context of some
598port, namely C<peval>: 606port, namely C<peval>:
599 607
600 peval $port, sub { 608 peval $port, sub {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines