File-SharedVar
view release on metacpan or search on metacpan
lib/File/SharedVar.pm view on Meta::CPAN
use File::SharedVar;
# Create a new shared variable object
my $shared_var = File::SharedVar->new(
file => '/tmp/ramdisk/sharedvar.dat',
create => 1, # Set to 1 to create or truncate the file
);
# Update a key
my $previous_value = $shared_var->update('foo', 1, 1); # Increment 'foo' by 1
# Read a key
my $value = $shared_var->read('foo');
print "Value of foo: $value\n";
=head1 DESCRIPTION
File::SharedVar provides an object-oriented interface to share variables between Perl processes using a file as shared storage, with working cross-platform file locking mechanisms to ensure data integrity in concurrent environments.
It allows you to read, update, and reset shared variables stored in a file (uses JSON format), making it easy to coordinate between multiple processes.
This module was written to serve as a functioning alternative to the incomplete and unmaintained "IPC::Shareable" module which has multiple unfixed bugs reported against it (and which shreds your shared memory under long-running processes)
=head2 CAUTION
This module relies on your filesystem properly supporting file locking (and your selection of a lockfile on that filesystem), which is not the case for Windows Services for Linux (WSL1 and WSL2) nor their "lxfs" filesystem. The bug has been reported...
The "test" phase of installing this module, when run on a system with broken locking, may take an extended amount of time to fail (many minutes or even hours).
A future version of this module is planned, optionally using a lockfile as a mutex for WSL, because flock() does not work properly in WSL1, WSL2, or their lxfs file systems (randomly throws "invalid argument" on seek() calls under heavy load).
=head2 WSL workaround
The mounted windows NTFS file system does support locking under WSL - use a lockfile on one of your "drvfs" (e.g. C: or /mnt/c) to have this module work properly there.
=cut
use strict;
use warnings;
use Fcntl qw(:DEFAULT :flock LOCK_EX LOCK_UN LOCK_NB O_RDWR O_EXCL O_CREAT);
#use Fcntl ':flock'; # For using O_EXCL and O_CREAT constants
#use Fcntl qw(:DEFAULT :flock O_EXCL O_CREAT O_RDWR); # Ensure proper constants are imported
#my($LOCK_EX,$LOCK_UN,$LOCK_NB,$O_RDWR)=(2,8,4,2); # These are required, because the $LOCK_* constants are sometimes not numbers, and inconveniently require "no strict 'subs';"
my($LOCK_EX,$LOCK_UN,$LOCK_NB,$O_RDWR,$O_EXCL,$O_CREAT)=(0+LOCK_EX,0+LOCK_UN,0+LOCK_NB,0+O_RDWR,0+O_EXCL,0+O_CREAT); # Avoid no strict 'subs' and nonnumber issues
our $VERSION = '1.00';
our $DEBUG = 0;
eval {
require JSON::XS;
JSON::XS->import; 1;
} or do {
require JSON;
JSON->import;
};
#my $json_text = encode_json($data);
#my $decoded_data = decode_json($json_text);
=head1 METHODS
=head2 new
my $shared_var = File::SharedVar->new(%options);
Creates a new `File::SharedVar` object.
=over 4
=item *
C<file>: Path to the shared variable file. Defaults to C</tmp/sharedvar$$.dat>.
C<mutex>: set this key to 'lock' to use file-existance locking instead of just flock(). Uses C<file.lock> for locking.
=item *
C<create>: If true (non-zero), the file will be created if it doesn't exist or truncated if it does. Defaults to C<0>.
=back
=cut
sub new {
my ($class, %args) = @_;
my $self = {
file => $args{file} // "/tmp/sharedvar$$.dat",
fh => undef,
};
bless $self, $class;
if ($args{create}) {
# Create or truncate the file
open my $fh, '>', $self->{file} or die "Cannot open $self->{file}: $!";
close $fh;
} elsif (!-f $self->{file}) {
die $self->{file},": No such file";
}
$self->{lock}=$self->{file}.".lock" if($args{mutex} && $args{mutex} eq 'lock');
return $self;
}
=head2 read
my $value = $shared_var->read($key);
Reads the value associated with the given key from the shared variable file.
=over 4
=item *
C<$key>: The key whose value you want to read.
( run in 0.831 second using v1.01-cache-2.11-cpan-df04353d9ac )