package PidFile::DatabaseCompat;
use strict;
use warnings 'all';
use DBI;
use Digest::MD5 qw(md5);
use FindBin;
use POSIX qw(strftime);
sub new {
my ($class, $keeper, %opts) = @_;
my ($crc1, $crc2) = map {abs unpack 'j',$_} grep {$_} split /(.{8})/, md5(($opts{pid_name}||$FindBin::RealScript).($opts{per_host} ? $opts{host} : ''));
my $self = {
dbh => $keeper->create_db_t_connect,
delay => exists $opts{delay} ? $opts{delay} : 30,
host => $opts{host},
mutex => $crc1^$crc2,
per_host => $opts{per_host},
script => "$FindBin::RealBin/$FindBin::RealScript",
verbose => $opts{verbose},
};
$self->{dbh}{PrintError} = 0;
$self->{dbh}{RaiseError} = 1;
bless $self, $class;
}
sub block {
my ($self, $now) = @_;
$self->{started} = $now;
# our candidature
$self->{dbh}->do("INSERT INTO pid (pid, mutex, host, script, started, state) VALUES (?,?,?,?,?,1)", {}, $$, $self->{mutex}, $self->{host}, $self->{script}, strftime('%Y-%m-%d %H:%M:%S', localtime $now));
$self->{id} = $self->{dbh}->selectrow_array("SELECT currval('documents_id_seq')");
$self->{dbh}->commit;
# election now
eval {
$self->{cands} = $self->{dbh}->selectall_arrayref("SELECT * FROM pid WHERE mutex=? AND state=1 FOR UPDATE NOWAIT", {Slice=>{}}, $self->{mutex});
};
if ($@ && $@=~/could not obtain lock on row/) {
$@ = "Found alive process, exit\n";
die $@ if $self->{verbose};
exit;
}
# is real winner?
unless (grep {$_->{id}==$self->{id}} @{$self->{cands}}) {
$@ = "Seems like other process overtaked, exit\n";
die $@ if $self->{verbose};
exit;
}
print "Created PID record (PID: $$) at ".localtime($now)."\n" if $self->{verbose};
}
sub release {
my ($self, $now) = @_;
my $sleep = $self->{delay} ? $self->{delay} - ($now - $self->{started}) : 0;
$sleep = 0 if $sleep<0;
if ($sleep) {
print "Sleeping for $sleep seconds before exit...\n" if $self->{verbose};
sleep $sleep;
}
for (@{$self->{cands}}) {
if ($_->{id}==$self->{id}) {
$self->{dbh}->do("UPDATE pid SET finished=?, state=2 WHERE id=?", {}, strftime('%Y-%m-%d %H:%M:%S', localtime $now), $self->{id});
} else {
$self->{dbh}->do("DELETE FROM pid WHERE id=?", {}, $_->{id});
}
}
$self->{dbh}->commit;
print "Removed PID record (PID: $$) at ".localtime($now)."\n" if $self->{verbose};
return $sleep;
}
sub DESTROY {
my $self = shift;
eval {
$self->{dbh}->disconnect;
};
}
1;
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.