| Cache-Memcached-AnyEvent documentation | Contained in the Cache-Memcached-AnyEvent distribution. |
Cache::Memcached::AnyEvent::Selector::Ketama - Ketama Server Selection Algorithm =head1 SYNOPSIS
use Cache::Memcached::AnyEvent;
my $memd = Cache::Memcached::AnyEvent->new({
...
selector_class => 'Ketama',
});
Implements the ketama server selection mechanism,
Constructor.
Called when a new server set is given
Returns the AnyEvent handle that is responsible for handling $key
| Cache-Memcached-AnyEvent documentation | Contained in the Cache-Memcached-AnyEvent distribution. |
package Cache::Memcached::AnyEvent::Selector::Ketama; use strict; use base qw(Cache::Memcached::AnyEvent::Selector::Traditional); use Algorithm::ConsistentHash::Ketama; use Carp qw(croak); sub new { my $class = shift; my $self = bless{ @_ }, $class; return $self; } sub set_servers { my ($self, $servers) = @_; my $ketama = $self->{ketama} = Algorithm::ConsistentHash::Ketama->new; foreach my $server (@$servers) { my ($host_port, $weight) = (ref $server eq 'ARRAY') ? @$server : ( $server, 1 ) ; $ketama->add_bucket($host_port, $weight); } } sub get_handle { my ($self, $key) = @_; my $count = $self->{memcached}->{_active_server_count}; if ($count > 0) { my $servers = $self->{memcached}->{_active_servers}; my $handles = $self->{memcached}->{_server_handles}; # short-circuit for when there's only one socket if ($count == 1) { return (values %$handles)[0]; } my $ketama = $self->{ketama}; while ( scalar keys %$handles > 0 ) { my $server = $ketama->hash($key); my $handle = $handles->{ $server }; if ($handle) { return $handle; } else { $ketama->remove_bucket($server); } } } croak "Could not find a suitable handle for key $key"; } 1; __END__