… | |
… | |
139 | delete $LOCAL_DBS{$node}; |
139 | delete $LOCAL_DBS{$node}; |
140 | } |
140 | } |
141 | |
141 | |
142 | # gather node databases from slaves |
142 | # gather node databases from slaves |
143 | |
143 | |
144 | # other node wants to make us the master |
144 | # other node wants to make us the master and sends us their db |
145 | $NODE_REQ{g_slave} = sub { |
145 | $NODE_REQ{g_slave} = sub { |
146 | my ($db) = @_ |
146 | my ($db) = @_ |
147 | or return; # empty g_slave is used to start global service |
147 | or return; # empty g_slave is used to start global service |
148 | |
148 | |
149 | my $node = $SRCNODE; |
149 | my $node = $SRCNODE; |
150 | undef $GLOBAL_SLAVE{$node}; |
150 | undef $GLOBAL_SLAVE{$node}; |
151 | g_set $node, $db; |
151 | g_set $node, $db; |
152 | }; |
152 | }; |
153 | |
153 | |
154 | # other node (global and slave) sends us their database |
154 | # other global node sends us their database |
155 | $NODE_REQ{g_set} = sub { |
155 | $NODE_REQ{g_set} = sub { |
|
|
156 | my ($db) = @_; |
|
|
157 | |
156 | &g_set ($SRCNODE, @_); |
158 | g_set $SRCNODE, $db; |
|
|
159 | |
|
|
160 | # a remote node always has to provide their listeners. for global |
|
|
161 | # nodes, we mirror their 'l locally, just as we also set 'g. |
|
|
162 | # that's not very efficient, but ensures that global nodes |
|
|
163 | # find each other. |
|
|
164 | db_set "'l" => $SRCNODE => $db->{"'l"}{$SRCNODE}; |
157 | }; |
165 | }; |
158 | |
166 | |
159 | # other node (global and slave) sends us a family update |
167 | # other node (global and slave) sends us a family update |
160 | $NODE_REQ{g_upd} = sub { |
168 | $NODE_REQ{g_upd} = sub { |
161 | &g_upd ($SRCNODE, @_); |
169 | &g_upd ($SRCNODE, @_); |
… | |
… | |
187 | |
195 | |
188 | sub g_disconnect($) { |
196 | sub g_disconnect($) { |
189 | my ($node) = @_; |
197 | my ($node) = @_; |
190 | |
198 | |
191 | db_del "'g" => $node; |
199 | db_del "'g" => $node; |
|
|
200 | db_del "'l" => $node; |
192 | g_clr $node; |
201 | g_clr $node; |
193 | |
202 | |
194 | if (my $mon = delete $GLOBAL_SLAVE{$node}) { |
203 | if (my $mon = delete $GLOBAL_SLAVE{$node}) { |
195 | while (my ($f, $fv) = each %$mon) { |
204 | while (my ($f, $fv) = each %$mon) { |
196 | delete $GLOBAL_MON{$f}{$_} |
205 | delete $GLOBAL_MON{$f}{$_} |
… | |
… | |
237 | |
246 | |
238 | # each node puts the set of connected global nodes into |
247 | # each node puts the set of connected global nodes into |
239 | # 'g - this causes a big duplication and mergefest, but |
248 | # 'g - this causes a big duplication and mergefest, but |
240 | # is the easiest way to ensure global nodes have a list |
249 | # is the easiest way to ensure global nodes have a list |
241 | # of all other global nodes. |
250 | # of all other global nodes. |
242 | |
251 | # we also mirror 'l as soon as we receive it, causing |
|
|
252 | # even more overhead. |
243 | db_set "'g" => $node; |
253 | db_set "'g" => $node; |
244 | |
254 | |
245 | # global nodes send all local databases of their slaves, merged, |
255 | # global nodes send all local databases of their slaves, merged, |
246 | # as their local database to other global nodes |
256 | # as their database to other global nodes |
247 | my %db; |
257 | my %db; |
248 | |
258 | |
249 | while (my ($k, $v) = each %LOCAL_DBS) { |
259 | while (my ($k, $v) = each %LOCAL_DBS) { |
250 | next unless exists $GLOBAL_SLAVE{$k}; |
260 | next unless exists $GLOBAL_SLAVE{$k}; |
251 | |
261 | |
252 | while (my ($f, $fv) = each %$_) { |
262 | while (my ($f, $fv) = each %$v) { |
253 | while (my ($k, $kv) = each %$fv) { |
263 | while (my ($k, $kv) = each %$fv) { |
254 | $db{$f}{$k} = $kv; |
264 | $db{$f}{$k} = $kv; |
255 | } |
265 | } |
256 | } |
266 | } |
257 | } |
267 | } |