… | |
… | |
138 | sub set_seeds(@) { |
138 | sub set_seeds(@) { |
139 | @SEEDS{@_} = (); |
139 | @SEEDS{@_} = (); |
140 | |
140 | |
141 | $SEED_WATCHER ||= AE::timer 5, $AnyEvent::MP::Kernel::MONITOR_TIMEOUT, \&more_seeding; |
141 | $SEED_WATCHER ||= AE::timer 5, $AnyEvent::MP::Kernel::MONITOR_TIMEOUT, \&more_seeding; |
142 | |
142 | |
143 | for (1 .. keys %SEEDS) { |
|
|
144 | after 0.100 * rand, \&more_seeding; |
143 | after 0.100 * rand, \&more_seeding |
145 | } |
144 | for 1 .. keys %SEEDS; |
146 | } |
145 | } |
147 | |
146 | |
148 | sub up_seeds() { |
147 | sub up_seeds() { |
149 | grep node_is_up $_, values %SEEDS |
148 | grep node_is_up $_, values %SEEDS |
150 | } |
149 | } |
… | |
… | |
372 | snd $port{$node}, nodes => \%addr if %addr; |
371 | snd $port{$node}, nodes => \%addr if %addr; |
373 | }, |
372 | }, |
374 | ; |
373 | ; |
375 | } |
374 | } |
376 | |
375 | |
|
|
376 | sub set_master($) { |
|
|
377 | return if $MASTER eq $_[0]; |
|
|
378 | |
|
|
379 | snd $port{$MASTER}, "seedme0" |
|
|
380 | if $MASTER && node_is_up $MASTER; |
|
|
381 | |
|
|
382 | $MASTER = $_[0]; |
|
|
383 | |
|
|
384 | if ($MASTER) { |
|
|
385 | snd $port{$MASTER}, "seedme1"; |
|
|
386 | $AnyEvent::MP::Kernel::WARN->(7, "selected new master: $MASTER."); |
|
|
387 | } else { |
|
|
388 | $AnyEvent::MP::Kernel::WARN->(1, "no contact to any other node."); |
|
|
389 | } |
|
|
390 | } |
|
|
391 | |
377 | sub mon_node { |
392 | sub mon_node { |
378 | my ($node, $is_up) = @_; |
393 | my ($node, $is_up) = @_; |
379 | |
394 | |
380 | if ($is_up) { |
395 | if ($is_up) { |
381 | ++$nodecnt; |
396 | ++$nodecnt; |
382 | start_node $node; |
397 | start_node $node; |
383 | } |
|
|
384 | |
398 | |
385 | # now select a new(?) master |
399 | if (node_is_seed $node) { |
386 | my $master; |
400 | if (node_is_seed $MASTER) { |
|
|
401 | my @SEEDS = up_seeds; |
387 | |
402 | |
388 | if (my @SEEDS = up_seeds) { |
|
|
389 | # switching here with lower chance roughly hopefully still gives us |
403 | # switching here with lower chance roughly hopefully still gives us |
390 | # an equal selection. |
404 | # an equal selection. |
391 | $master = node_is_up $MASTER && node_is_seed $MASTER && 1 < rand @SEEDS |
405 | set_master $node |
392 | ? $MASTER |
406 | if 1 < rand @SEEDS; |
|
|
407 | } else { |
|
|
408 | # a seed always beats a non-seed |
|
|
409 | set_master $node; |
|
|
410 | } |
|
|
411 | } |
|
|
412 | } |
|
|
413 | |
|
|
414 | # select a new(?) master, if required |
|
|
415 | unless ($MASTER and node_is_up $MASTER) { |
|
|
416 | if (my @SEEDS = up_seeds) { |
393 | : $SEEDS[rand @SEEDS]; |
417 | set_master $SEEDS[rand @SEEDS]; |
394 | } else { |
|
|
395 | # select "last" non-seed node |
|
|
396 | $master = (sort +up_nodes)[-1]; |
|
|
397 | #TODO maybe avoid listener-less nodes? |
|
|
398 | } |
|
|
399 | |
|
|
400 | if ($MASTER ne $master) { |
|
|
401 | snd $port{$MASTER}, "seedme0" |
|
|
402 | if $MASTER && node_is_up $MASTER; |
|
|
403 | |
|
|
404 | $MASTER = $master; |
|
|
405 | if ($MASTER) { |
|
|
406 | snd $port{$MASTER}, "seedme1"; |
|
|
407 | $AnyEvent::MP::Kernel::WARN->(7, "selected new master: $MASTER."); |
|
|
408 | } else { |
418 | } else { |
409 | $AnyEvent::MP::Kernel::WARN->(1, "no contact to any other node."); |
419 | # select "last" non-seed node |
|
|
420 | set_master +(sort +up_nodes)[-1]; |
410 | } |
421 | } |
411 | } |
422 | } |
412 | |
423 | |
413 | unless ($is_up) { |
424 | unless ($is_up) { |
414 | --$nodecnt; |
425 | --$nodecnt; |