If a pool is empty or low on nodes, this is not handled until a new request is made to the same pool.
But if a new node is added to the pool, pending requests should be
directed to it to it immediately. This is important in environments
where nodes are added and removed from pools frequently.
I have made a patch for that. The pull request can be seen here:
https://github.com/perlbal/Perlbal/pull/20The change itself is quite simple: Just make it possible for a Service to register itself when it hits the nodecount ceiling. When nodes are added, it will check whether any service is still waiting for nodes.
index a6d88a1..df634da 100644
--- a/lib/Perlbal/Pool.pm
+++ b/lib/Perlbal/Pool.pm
@@ -32,6 +32,7 @@ use fields (
'nodefile.lastmod', # unix time nodefile was last modified
'nodefile.lastcheck', # unix time nodefile was last stated
'nodefile.checking', # boolean; if true AIO is stating the file for us
+ 'waiting_services', # a hash of services waiting for this pool
);
sub new {
@@ -49,6 +50,7 @@ sub new {
$self->{nodefile} = undef;
$self->{balance_method} = BM_RANDOM;
+ $self->{waiting_services} = {};
return $self;
}
@@ -214,6 +216,18 @@ sub add {
$self->{node_used}->{"$ip:$port"} = 0;
push @{$self->{nodes}}, [ $ip, $port ];
$self->{node_count} = scalar(@{$self->{nodes}});
+
+ if ($self->{waiting_services}) {
+ foreach my $service (values %{$self->{waiting_services}}) {
+ next unless $service;
+ delete $self->{waiting_services}->{$service->{name}};
+ if ($service->{waiting_client_count} >0) {
+ Perlbal::log('info', "Pool $self->{name} was added much needed node. Now has " . $self->node_count . " nodes");
+ $service->spawn_backends;
+ last; # We only have enough for one.
+ }
+ }
+ }
}
sub remove {
diff --git a/lib/Perlbal/Service.pm b/lib/Perlbal/Service.pm
index 3e87dd8..2e8457e 100644
--- a/lib/Perlbal/Service.pm
+++ b/lib/Perlbal/Service.pm
@@ -1442,6 +1442,14 @@ sub spawn_backends {
# can't create more than this, assuming one pending connect per node
my $max_creatable = $pool ? ($self->{pool}->node_count - $self->{pending_connect_count}) : 1;
+
+ # If we cannot create any backends, register this service as waiting for nodes
+ if ($pool and $max_creatable <= 0 and $to_create > 0) {
+ $pool->{waiting_services}->{$self->{name}} = $self;
+ } else {
+ delete $pool->{waiting_services}->{$self->{name}};
+ }
+
$to_create = $max_creatable if $to_create > $max_creatable;
# cap number of attempted connects at once