use strict;
use warnings;
package KinoSearch::Store::LockFactory;
use KinoSearch::Util::ToolSet;
use base qw( KinoSearch::Util::Obj );
our %instance_vars = (
# params
folder => undef,
agent_id => undef,
);
use KinoSearch::Store::Lock;
use KinoSearch::Store::SharedLock;
our %make_lock_vars = (
lock_name => undef,
timeout => undef,
);
1;
__END__
__XS__
MODULE = KinoSearch PACKAGE = KinoSearch::Store::LockFactory
kino_LockFactory*
new(...)
CODE:
{
/* parse params */
HV *const args_hash = build_args_hash( &(ST(0)), 1, items,
"KinoSearch::Store::LockFactory::instance_vars");
kino_Folder *folder = (kino_Folder*)extract_obj(args_hash,
SNL("folder"), "KinoSearch::Store::Folder");
SV *agent_id_sv = extract_sv(args_hash, SNL("agent_id"));
kino_ByteBuf agent_id = KINO_BYTEBUF_BLANK;
if (!SvOK(agent_id_sv))
CONFESS("missing required parameter 'agent_id'");
SV_TO_TEMP_BB(agent_id_sv, agent_id);
/* create object */
RETVAL = kino_LockFact_new(folder, &agent_id);
}
OUTPUT: RETVAL
kino_Lock*
_create_a_lock(self, ...);
kino_LockFactory *self;
ALIAS:
make_lock = 1
make_shared_lock = 2
CODE:
{
/* parse params */
HV *const args_hash = build_args_hash( &(ST(0)), 1, items,
"KinoSearch::Store::LockFactory::make_lock_vars");
chy_i32_t timeout = extract_iv(args_hash, SNL("timeout"));
SV *lock_name_sv = extract_sv(args_hash, SNL("lock_name"));
kino_ByteBuf lock_name = KINO_BYTEBUF_BLANK;
if (!SvOK(lock_name_sv))
CONFESS("missing required parameter 'lock_name'");
SV_TO_TEMP_BB(lock_name_sv, lock_name);
/* create object */
if (ix == 1) {
RETVAL = Kino_LockFact_Make_Lock(self, &lock_name, timeout);
}
else {
RETVAL = (kino_Lock*)Kino_LockFact_Make_Shared_Lock(self,
&lock_name, timeout);
}
}
OUTPUT: RETVAL
__POD__
=head1 NAME
KinoSearch::Store::LockFactory - Create Locks.
=head1 SYNOPSIS
use Sys::Hostname;
my $hostname = hostname();
die "Can't get unique hostname" unless $hostname;
my $invindex = MySchema->open('/path/to/invindex/on/nfs/volume');
my $lock_factory = KinoSearch::Store::LockFactory->new(
folder => $invindex->get_folder,
agent_id => $hostname,
);
my $index_reader = KinoSearch::Index::IndexReader->new(
invindex => $invindex,
lock_factory => $lock_factory,
);
=head1 DESRIPTION
Normally, LockFactory is an internal class, quietly doing its work behind the
scenes. On shared volumes, however, the locking mechanism fails, and manual
intervention becomes necessary.
Both reading and writing applications accessing an index on a shared volume
need to identify themselves with an C<agent_id>, typically the hostname.
Knowing the hostname makes it possible to tell which lockfiles belong to other
machines and therefore must not be zapped when their pid can't be found.
=head2 Subclassing
LockFactory spins off L<Lock|KinoSearch::Store::Lock> and
L<SharedLock|KinoSearch::Store::SharedLock> objects at the request of other
KinoSearch classes. If the behavior of Lock and SharedLock do not suit your
needs, you may substitute a custom subclass of LockFactory which spins off
your own Lock subclasses.
=head1 CONSTRUCTOR
my $lock_factory = KinoSearch::Store::LockFactory->new(
folder => $folder, # required
agent_id => $hostname, # required
);
Create a LockFactory. Takes named parameters.
=over
=item *
B<folder> - A L<KinoSearch::Store::Folder>.
=item *
B<agent_id> - An identifying string -- typically, the hostname.
=back
=head1 METHODS
=head2 make_lock
my $exclusive_lock = $lock_factory->make_lock(
lock_name => 'foo',
timeout => 5000,
);
Returns an exclusive lock on a resource. Called with two hash-style
parameters, C<lock_name> and C<timeout>, which are passed on to Lock's
constructor.
=head2 make_shared_lock
my $shared_lock = $lock_factory->make_lock(
lock_name => 'foo',
timeout => 5000,
);
Returns a shared lock on a resource. Called with two hash-style parameters,
C<lock_name> and C<timeout>, which are passed on to SharedLock's constructor.
=head1 COPYRIGHT
Copyright 2007 Marvin Humphrey
=head1 LICENSE, DISCLAIMER, BUGS, etc.
See L<KinoSearch> version 0.20.
=cut