🗃 Store::Directories 🗃
Manage a key/value store of directories with controls for concurrent access and locking.
Version: 0.2
SYNOPSIS
use Store::Directories;
# Create a new store at given directory
# (or adopt one that is already there)
my $store = Store::Directories->init("path/to/store/")
# (In this example, we create a new directory containing a text file
# and then atomically increment the value written in the file)
my $value = 1;
# Get a directory with the key 'foo' in the store,
# creating it if it doesn't exist yet
my $lock;
my $dir = $store->get_or_add('foo' {
# as an option, we can provide a subroutine to use to
# initialize the directory contents if we create it
# (but if the directory already exists, this won't be called)
init => sub {
my $dir = shift;
open(my $fh, '>', "$dir/hello.txt") or die "could not open file: $!";
print $fh $value;
close $fh;
}
});
{
# Get an exclusive lock on the directory before reading/writing to it.
# This ensure no other process is reading or modifying the directory
# contents while we're working.
my $lock = $store->lock_ex('foo');
open(my $fh, '<', "$dir/hello.txt") or die "could not open file: $!";
$value = <$fh>;
open($fh, '>', "$dir/hello.txt") or die "could not re-open file: $!";
print $fh $value + 1;
close $fh;
# The lock is released once $lock is out-of-scope
}
DESCRIPTION
Store::Directories manages a key/value store of directories and allows processes to assert shared (read-only) or exclusive (writable) locks on those directories.
Directories in a Store::Directories Store are referenced by unique string "keys". Internally, the directories are named with hexadecimal UUIDS, so the keys you use to identify them can contain illegal or unusual characters for filenames. (web URLs are a common example).
Processes can perform operations on these directories in parallel by requesting
"locks" on particualr directories. These locks can be either shared or
exclusive (to borrow flock(2) terminology). Lock objects are obtained
with the lock_sh or lock_ex methods of a Store::Directories instance
and are automatically released once they go out of scope.
Shared locks are used when a process wants to read, but not modify the contents of a directory while being sure that no other process can modify the contents while its reading. There can be multiple shared locks from different processes on a directory at once, but never at the same time as an exclusive lock.
Exclusive locks are used when a process wants to read and modify the contents of a directory while being sure that no other process can modify or read the contents while its working. There can only be one exclusive lock on a directory at once and there can't be any shared locks with it.
If a process requests a lock that is unavailable at the moment (due to another process already having an incompatible lock), then the process will block until the lock can be obtained (either by the other process dying or releasing its locks). Be aware that the order in which locks are granted is not necessarily the same order that that they were requested in.
WARNING: The guarantees around locking make the assumption that every process is using this package and playing by its rules. Unrelated processes are free to ignore the rules and mess things up as much as they like.
Documentation
For full documentation, please see the man pages installed with the module or the page on MetaCPAN HERE.
AUTHOR
Cameron Tauxe camerontauxe@gmail.com
LICENSE AND COPYRIGHT
This software is copyright (c) 2020 by Cameron Tauxe.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.