ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/Global.pm
Revision: 1.45
Committed: Wed Feb 29 18:58:23 2012 UTC (12 years, 3 months ago) by root
Branch: MAIN
Changes since 1.44: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     AnyEvent::MP::Global - some network-global services
4    
5     =head1 SYNOPSIS
6    
7     use AnyEvent::MP::Global;
8    
9     =head1 DESCRIPTION
10    
11 root 1.42 This module maintains a fully-meshed network between global nodes and
12     tries to have connections with all nodes in the network.
13 root 1.1
14 root 1.15 It also manages named port groups - ports can register themselves in any
15     number of groups that will be available network-wide, which is great for
16     discovering services.
17 root 1.1
18 root 1.15 Running it on one node will automatically run it on all nodes, although,
19     at the moment, the global service is started by default anyways.
20 root 1.3
21 root 1.1 =head1 GLOBALS AND FUNCTIONS
22    
23     =over 4
24    
25     =cut
26    
27     package AnyEvent::MP::Global;
28    
29     use common::sense;
30     use Carp ();
31    
32 root 1.8 use AnyEvent ();
33 root 1.4 use AnyEvent::Util ();
34    
35 root 1.1 use AnyEvent::MP;
36     use AnyEvent::MP::Kernel;
37 root 1.22 use AnyEvent::MP::Transport ();
38 root 1.1
39 root 1.20 use base "Exporter";
40    
41     our @EXPORT = qw(
42     grp_reg
43     grp_get
44     grp_mon
45     );
46    
47 root 1.5 $AnyEvent::MP::Kernel::WARN->(7, "starting global service.");
48    
49 root 1.8 #############################################################################
50 root 1.44 # node protocol parts for global nodes
51 root 1.8
52 root 1.44 {
53     package AnyEvent::MP::Kernel;
54 root 1.8
55 root 1.44 # TODO: this is ugly, maybe this should go into MP::Kernel or a separate module #d#
56 root 1.26
57 root 1.44 our $GLOBAL;
58 root 1.45 our $MASTER;
59 root 1.44 our $NODE_ADDR;
60     our $GLOBAL_ADDR;
61     our $NODE;
62     our %GLOBAL_SLAVE;
63     our $GLOBAL_MON;
64     our $LISTENER;
65 root 1.26
66 root 1.44 # switch to global mode
67     $GLOBAL = 1;
68     $MASTER = $NODE;
69     undef $GLOBAL_MON;
70 root 1.22
71 root 1.44 $GLOBAL_ADDR->{$NODE} = $LISTENER;
72 root 1.8
73 root 1.44 $GLOBAL_MON = mon_nodes sub {
74     return if $_[1];
75 root 1.20
76 root 1.44 delete $NODE_ADDR->{$_[0]};
77 root 1.20
78 root 1.44 if (delete $GLOBAL_ADDR->{$_[0]}) {
79     # if the node is global, tell our slaves
80 root 1.20
81 root 1.44 our %GLOBAL_SLAVE; # ugh, will be in AnyEvent::MP::Global
82     snd $_, g_del => $_[0]
83     for keys %GLOBAL_SLAVE;
84     }
85     };
86 root 1.20
87 root 1.44 # tell everybody who connects that we are a global node
88     push @AnyEvent::MP::Transport::HOOK_GREET, sub {
89     $_[0]{local_greeting}{global} = 1;
90     };
91 root 1.4
92 root 1.44 # tell every global node that connects that we are global too
93     push @AnyEvent::MP::Transport::HOOK_CONNECT, sub {
94     snd $_[0], g_add => $NODE, $LISTENER
95     if $_[0]{remote_greeting}{global};
96     };
97 root 1.4
98 root 1.44 # tell everybody else that we are global now
99     snd $_ => g_add => $NODE, $LISTENER
100     for up_nodes;
101 root 1.4 }
102    
103 root 1.20 =item $guard = grp_reg $group, $port
104 root 1.4
105     Register the given (local!) port in the named global group C<$group>.
106    
107     The port will be unregistered automatically when the port is destroyed.
108    
109     When not called in void context, then a guard object will be returned that
110     will also cause the name to be unregistered when destroyed.
111    
112     =cut
113    
114     # register local port
115 root 1.20 sub grp_reg($$) {
116     my ($group, $port) = @_;
117 root 1.4
118     port_is_local $port
119 root 1.20 or Carp::croak "AnyEvent::MP::Global::grp_reg can only be called for local ports, caught";
120    
121 root 1.44 defined wantarray && AnyEvent::Util::guard { unregister ($port, $group) }
122 root 1.4 }
123    
124 root 1.20 =item $ports = grp_get $group
125 root 1.15
126     Returns all the ports currently registered to the given group (as
127 root 1.20 read-only(!) array reference). When the group has no registered members,
128 root 1.15 return C<undef>.
129    
130     =cut
131    
132 root 1.20 sub grp_get($) {
133     }
134    
135     =item $guard = grp_mon $group, $callback->($ports, $add, $del)
136    
137     Installs a monitor on the given group. Each time there is a change it
138     will be called with the current group members as an arrayref as the
139     first argument. The second argument only contains ports added, the third
140     argument only ports removed.
141    
142     Unlike C<grp_get>, all three arguments will always be array-refs, even if
143     the array is empty. None of the arrays must be modified in any way.
144    
145     The first invocation will be with the first two arguments set to the
146     current members, as if all of them were just added, but only when the
147 root 1.39 group is actually non-empty.
148 root 1.20
149     Optionally returns a guard object that uninstalls the watcher when it is
150     destroyed.
151    
152     =cut
153    
154     sub grp_mon($$) {
155     my ($grp, $cb) = @_;
156 root 1.4 }
157 root 1.3
158 root 1.1 =back
159    
160     =head1 SEE ALSO
161    
162     L<AnyEvent::MP>.
163    
164     =head1 AUTHOR
165    
166     Marc Lehmann <schmorp@schmorp.de>
167     http://home.schmorp.de/
168    
169     =cut
170    
171     1
172