Apache-Session-libmemcached
view release on metacpan or search on metacpan
lib/Apache/Session/Store/libmemcached.pm view on Meta::CPAN
If load balance is enabled it will read from the right cache.
If it fails and failover is enabled, it will try to read
from other pools.
=cut
sub _read_session {
my ($self, $session) = @_;
my $args = $session->{args};
# Select pool
my ($idx, @alternative_pools) = $self->_select_read_pool($session);
# Read session and return it if everything is ok
my $ret = $self->_read_from_pool($session, $idx);
if (defined($ret) || !$args->{failover} || !@alternative_pools) {
return $ret;
}
# Try other pools if failover is enabled
for my $pool (@alternative_pools) {
$ret = $self->_read_from_pool($session, $pool);
last if (defined($ret));
}
return $ret;
}
=head2 _select_read_pool
Private method to select a pool to read from.
We just use 'first session id character' mod $numberOfPools to
select a pool.
Note that we return the first available pool if load balance is
not enabled or if there is only one pool.
=cut
sub _select_read_pool
{
my ($self, $session) = @_;
my $args = $session->{args};
my $sid = $session->{data}->{_session_id};
my $num_pools = 1;
my $idx = 0;
my @alternative_pools;
if ($sid && length($sid) && $args->{load_balance_pools}) {
$num_pools = scalar(@{$args->{load_balance_pools}});
$idx = hex(substr($sid, 0, 1)) % $num_pools;
@alternative_pools = map { $_ != $idx } 0..($num_pools - 1);
}
return ($idx, @alternative_pools);
}
=head2 _update_pools
Private method to return which pools must be updated.
If failover is not enabled only one pool is returned.
Otherwise the designated pool will be returned.
=cut
sub _update_pools
{
my ($self, $session) = @_;
my @pools;
# If failover is enabled remove from available pools,
# otherwise update designated pool.
if ($session->{args}->{failover}) {
@pools = @{$self->{libmemcached}};
} else {
my ($idx, @alternative_pools) = $self->_select_read_pool($session);
return ($self->{libmemcached}->[$idx]);
@pools = ($self->{libmemcached}->[$idx]);
}
return @pools;
}
=head2 _read_from_pool
Private method to read from a given pool.
If read fails it will log the error in case logging is enabled.
=cut
sub _read_from_pool {
my ($self, $session, $pool) = @_;
my $instance = $self->{libmemcached}->[$pool]->{instance};
my $key = $session->{data}->{_session_id};
my $value = $instance->memcached_get($key);
my $log = $session->{args}->{log_errors};
if ($log && !defined($value) && $instance->errstr() ne 'NOT FOUND') {
my $servers = $self->{libmemcached}->[$pool]->{servers};
my $errmsg = sprintf(
'Failed get %s in pool with %s',
join(' ', @{$servers}),
$instance->errstr()
);
$self->_log_error_message($errmsg);
}
return $value;
}
=head2 _write_session
Private method to set a key-value entry in all the configured pools.
=cut
sub _write_session {
my ($self, $op, $session) = @_;
( run in 0.583 second using v1.01-cache-2.11-cpan-2398b32b56e )