lemonldap-ng/modules/apache-session-memorycached/lib/Apache/Session/MemcachedClient.pm

179 lines
5.0 KiB
Perl

package Apache::Session::MemcachedClient;
use Apache::Session::Memorycached;
use Fcntl qw(:DEFAULT :flock);
$| = 1;
our $VERSION = '2.1.1';
sub new {
my $class = shift;
my %args = @_;
my $self;
$self = \%args;
bless $self, $class;
}
sub run {
my $self = shift;
my $file_input = $self->{in_file};
my $file_output = $self->{out_file};
my $naptime = $self->{naptime} || '1';
my $safetime = $self->{safetime} || '900'; # 15 minutes
for ( ; ; ) {
sysopen( FH, $file_input, O_RDWR | O_CREAT ) || die "$file_input $!\n";
flock( FH, LOCK_EX );
my @ligne = <FH>;
seek( FH, 0, 0 );
truncate( FH, 0 );
close(FH);
my @log;
for (@ligne) {
( my $session, my $time ) = /^(\w+)\s(\d+)/;
### retrieve session
my $param = $self->{localmemcached};
my $sign = $self->{signature} || 'master';
my %localsession;
my %remotesession;
tie %localsession, 'Apache::Session::Memorycached', $session,
$param;
if ( !%localsession ) {
### error in retrieve session
untie %localsession;
push @log, "FATAL :$session FAILED \n";
next;
}
my %_localsession = %localsession;
untie %localsession;
#######################################
## avoid loop in master2master case ##
#######################################
if ( $_localsession{$sign} ) {
### pehap already replicated
# exept in this case
my $time_origine = $_localsession{$sign};
$time_origine =~ s/#.+$//;
if ( ( time - $time_origine ) < $safetime ) {
push @log, "INFO :$session SYN OK\n";
next;
}
}
$_localsession{$sign} = time . "#" . $time;
#### and send this to the other server
my $paramdist = $self->{remotememcached};
##### ne marche pas $session exist ########
my %remotesession;
tie %remotesession, 'Apache::Session::Memorycached', $session,
$paramdist;
if (%remotesession) {
### error in retrieve remote session
my $time_origine = $remotesession{$sign};
$time_origine =~ s/#.+$//;
next if ( ( time - $time_origine ) < $safetime );
}
%remotesession = %_localsession;
untie %remotesession;
push @log, "INFO :$session REPLICATED\n";
if ( $self->{safety_mode} ) {
my %remotesession;
### we retrieve session from the other memcached server
my $paramdist = $self->{remotememcached};
tie %remotesession, 'Apache::Session::Memorycached', $session,
$paramdist;
my %_remotesession = %remotesession;
untie %remotesession;
if ( $_remotesession{$sign} ) {
push @log, "INFO :$session VERIFIED\n";
}
else {
push @log, "FATAL :$session REPLICATION ERROR\n";
}
}
}
sysopen( FS, $file_output, O_WRONLY | O_APPEND | O_CREAT )
|| die "$file_output $!\n";
flock( FS, LOCK_EX );
for (@log) {
print FS $_;
}
close(FS);
sleep $naptime;
}
}
1;
=pod
=head1 NAME
Apache::Session::MemcachedClient - A component of memcached's replication
=head1 SYNOPSIS
use Apache::Session::MemcachedClient ;
my $rep = MemcachedClient->new(in_file =>"/tmp/logmem1",
out_file =>"/tmp/log1",
naptime => 2 ,
localmemcached => {'servers' => ['localhost:11211'], },
remotememcached =>{'servers' => ['localhost:11311'], },
signature => 'master11211',
safety_mode =>'actived' ,
);
$rep->run ;
exit;
=head1 DESCRIPTION
This module is an implementation of replication for memcached backend session storage . It replicates session created by Apache::Session::Memorycached between master to slave OR master to master.
In input , it reads a file issued from Apache::Session::MemcachedReplicator then it sends session on the other memcached server .
The lemonldap project (SSO under GPL) uses this module
=head1 Options
- in_file : input file .
- out_file : log in output file
- naptime : time between 2 cycles (in second)
- localmemcached : you local server
- remotememcached : you remote server (pehap the slave)
- signature : string used in order to avoid loops replication
- safety_mode : thrue : read on remote server after write in order to be sure of success of replication
see client_memcached.pl in script directory.
=head1 AUTHOR
This module was written by eric german <germanlinux@yahoo.fr>.
=head1 SEE ALSO
L<Apache::Session::MemcachedReplicator>,
L<Apache::Session::Memorycached>,