Sys::Tlock - Locking with timeouts.
0.12
use Sys::Tlock dir => '/var/myscript/locks/' , qw(tlock_take $patience);
print "tlock patience is ${patience}\n";
# taking a tlock for 5 minutes
tlock_take('logindex',300) || die 'Failed taking the tlock.';
my $token = $_;
move_old_index();
# hand over to that other script
exec( "/usr/local/loganalyze/loganalyze" , $token );
-----------------------------------------------------------
use Sys::Tlock;
# /etc/tlock.conf sets dir to "/var/myscript/locks/"
# checking lock is alive
my $t = $ARGV[0];
die 'Tlock not taken.' if not tlock_alive('logrotate',$t);
do_fancy_log_rotation(547);
system( './clean-up.sh' , $t ) or warn 'Clean-up failed.';
# releasing the lock
tlock_release('logrotate',$t);
This module is handling tlocks, advisory locks with timeouts.
They are implemented as simple directories that are created and deleted in the lock directory.
A distant predecessor to this module was written many years ago as a kludge to make locking work properly on a Windows server. But it turned out to be very handy to have tlocks in the filesystem, giving you an at-a-glance overview of them. Even the non-scripting sysadmins could easily view and manipulate tlocks.
The module is designed to allow separate programs to use the same tlocks between them. Even programs written in different languages. To do this safely, tlocks are paired with a lock token.
The configuration parameters are set using this process:
On top of this, you can import the $dir, $marker and $patience variables and change them in your script. But that is a recipe for disaster, so know what you do, if you go that way.
Configuration files must start with a "tlock 0" line. Empty lines are allowed and so are comments starting with the # character. There are three directives:
dir
For setting the lock directory. Write the full path.marker
For the marker (prefix) that all tlock directory names will get.patience
For the time that the take method will wait for a lock release. tlock 0
# Example configuration file for tlock.
dir /var/loglocks/
patience 7.5
Safe use of tlocks involve tokens, which are just timestamps of when the lock was taken.
Without tokens, something like this could happen...
script1 takes lockA
script1 freezes
lockA times out
script2 takes lockA
script1 resumes
script1 releases lockA
script3 takes lockA
Now both script2 and script3 "have" lockA!
Each tlock is a subdirectory of the lock directory. Their names are "${marker}.${label}". The default value for $marker is "tlock".
Each of the tlock directories has a sub directory named "d". The mtimes of these two directories saves the token and the timeout. There also are some very shortlived directories named "${marker}_.${label}". They are per label master locks. They help making changes to the normal locks atomic.
Loaded by default: tlock_take, tlock_renew, tlock_release, tlock_alive, tlock_taken, tlock_expiry, tlock_zing
Loaded on demand: tlock_tstart, tlock_release_careless, tlock_token, $dir, $marker, $patience
Take the tlock with the given label, and set its timeout. The call returns the associated token.
Labels can be any non-empty string consisting of letters a-z or A-Z, digits 0-9, dashes "-", underscores "_" and dots "." (PCRE: [a-zA-Z0-9\-\_\.]+)
It is possible to set a per call special patience value, by adding it as a third variable, like this: tlock_take( 'busylock' , $t , 600 )
The token value is also assigned to the $_ variable.
Reset the timeout of the tlock, so that it will time out $timeout seconds from the time that tlock_renew is called.
Release the tlock.
Returns true if the tlock is currently taken.
Returns true if a tlock with the given label is currently taken.
The difference between tlock_taken and tlock_alive, is that alive can differentiate between different tlocks with the same label. Different tlocks with the same label can exist at different points in time.
Returns the time when the current tlock with the given label will expire. It is given in epoch seconds.
Cleans up locks in the lock directory. Takes care not to mess with any lock activity.
Returns the time for the creation of the current tlock with the given label. It is given in epoch seconds. This function and the token function are identical.
Only loaded on demand.
Carelessly release any tlock with the given label, not caring about the token.
Only loaded on demand.
Returns the token for the current tlock with the given label.
Only loaded on demand.
The directory containing the tlocks.
Only loaded on demand.
The common prefix of the directory names used for tlocks.
Prefixes can be any non-empty string consisting of letters a-z or A-Z, digits 0-9, dashes "-" and underscores "_" (PCRE: [a-zA-Z0-9\-\_]+). First character has to be a letter, and last character a letter or digit.
Only loaded on demand.
Patience is the time a method will try to take or change a tlock, before it gives up. For example when tlock_take tries to take a tlock that is already taken, it is the number of seconds it should wait for that tlock to be released before giving up.
Dont confuse patience with timeout.
Default patience value is 2.5 seconds.
Only loaded on demand.
File::Basename
Time::HiRes
The author dare not guarantee that the locking is waterproof. But if there are conditions that breaks it, they must be very special. At the least, experience has shown it to be waterproof in practice.
Not tested on Windows, ironically enough.
flock
(c) 2022-2023 Bjoern Hee Licensed under the Apache License, version 2.0 https://www.apache.org/licenses/LICENSE-2.0.txt