ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/Global.pm
Revision: 1.44
Committed: Wed Feb 29 18:44:59 2012 UTC (12 years, 3 months ago) by root
Branch: MAIN
Changes since 1.43: +39 -259 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     our $NODE_ADDR;
59     our $GLOBAL_ADDR;
60     our $NODE;
61     our %GLOBAL_SLAVE;
62     our $GLOBAL_MON;
63     our $LISTENER;
64 root 1.26
65 root 1.44 # switch to global mode
66     $GLOBAL = 1;
67     $MASTER = $NODE;
68     undef $GLOBAL_MON;
69 root 1.22
70 root 1.44 $GLOBAL_ADDR->{$NODE} = $LISTENER;
71 root 1.8
72 root 1.44 $GLOBAL_MON = mon_nodes sub {
73     return if $_[1];
74 root 1.20
75 root 1.44 delete $NODE_ADDR->{$_[0]};
76 root 1.20
77 root 1.44 if (delete $GLOBAL_ADDR->{$_[0]}) {
78     # if the node is global, tell our slaves
79 root 1.20
80 root 1.44 our %GLOBAL_SLAVE; # ugh, will be in AnyEvent::MP::Global
81     snd $_, g_del => $_[0]
82     for keys %GLOBAL_SLAVE;
83     }
84     };
85 root 1.20
86 root 1.44 # tell everybody who connects that we are a global node
87     push @AnyEvent::MP::Transport::HOOK_GREET, sub {
88     $_[0]{local_greeting}{global} = 1;
89     };
90 root 1.4
91 root 1.44 # tell every global node that connects that we are global too
92     push @AnyEvent::MP::Transport::HOOK_CONNECT, sub {
93     snd $_[0], g_add => $NODE, $LISTENER
94     if $_[0]{remote_greeting}{global};
95     };
96 root 1.4
97 root 1.44 # tell everybody else that we are global now
98     snd $_ => g_add => $NODE, $LISTENER
99     for up_nodes;
100 root 1.4 }
101    
102 root 1.20 =item $guard = grp_reg $group, $port
103 root 1.4
104     Register the given (local!) port in the named global group C<$group>.
105    
106     The port will be unregistered automatically when the port is destroyed.
107    
108     When not called in void context, then a guard object will be returned that
109     will also cause the name to be unregistered when destroyed.
110    
111     =cut
112    
113     # register local port
114 root 1.20 sub grp_reg($$) {
115     my ($group, $port) = @_;
116 root 1.4
117     port_is_local $port
118 root 1.20 or Carp::croak "AnyEvent::MP::Global::grp_reg can only be called for local ports, caught";
119    
120 root 1.44 defined wantarray && AnyEvent::Util::guard { unregister ($port, $group) }
121 root 1.4 }
122    
123 root 1.20 =item $ports = grp_get $group
124 root 1.15
125     Returns all the ports currently registered to the given group (as
126 root 1.20 read-only(!) array reference). When the group has no registered members,
127 root 1.15 return C<undef>.
128    
129     =cut
130    
131 root 1.20 sub grp_get($) {
132     }
133    
134     =item $guard = grp_mon $group, $callback->($ports, $add, $del)
135    
136     Installs a monitor on the given group. Each time there is a change it
137     will be called with the current group members as an arrayref as the
138     first argument. The second argument only contains ports added, the third
139     argument only ports removed.
140    
141     Unlike C<grp_get>, all three arguments will always be array-refs, even if
142     the array is empty. None of the arrays must be modified in any way.
143    
144     The first invocation will be with the first two arguments set to the
145     current members, as if all of them were just added, but only when the
146 root 1.39 group is actually non-empty.
147 root 1.20
148     Optionally returns a guard object that uninstalls the watcher when it is
149     destroyed.
150    
151     =cut
152    
153     sub grp_mon($$) {
154     my ($grp, $cb) = @_;
155 root 1.4 }
156 root 1.3
157 root 1.1 =back
158    
159     =head1 SEE ALSO
160    
161     L<AnyEvent::MP>.
162    
163     =head1 AUTHOR
164    
165     Marc Lehmann <schmorp@schmorp.de>
166     http://home.schmorp.de/
167    
168     =cut
169    
170     1
171