RevBank::FileIO - Line-based text file manipulation with advisory locking
with_lock {
...
};
my $data = slurp $filename;
my @lines = slurp $filename;
spurt $filename, @data;
append $filename, @data;
rewrite $filename, sub($line) {
return $line; # return changed or unchanged line
return undef; # exclude line from file
};
This package implements very simple locking to protect against filesystem based race conditions when running multiple instances of revbank on the same data files.
These race conditions are probably exceptionally rare and very hard to trigger in real-world conditions, because file system access is very fast due to caching and buffering by the kernel. RevBank was used for over a decade without any known problem due such a race condition, before locking was finally added.
No attempt was made to optimize for performance, and all locks are global and exclusive.
Will wait for the global lock for as long as it takes, printing a message every few seconds to keep the user informed.
Gets the lock, executes the block, releases the lock again. Returns whatever the block returned.
Use this instead of get_lock
to prevent forgetting to release the lock.
Acquires the lock if it is not already held. Keeps extra virtual locks (by virtue of a simple counter) if the global lock is already held by the current process.
Calling this function directly is discouraged. Use with_lock
instead.
Decreases the number of virtual locks, releasing the real lock if none are left.
Calling this function directly is discouraged. Use with_lock
instead.
Returns the entire contents of the file. In list context, returns a list of lines (including the line ending).
Writes to a file. No separators or delimiters are added to the provided data, so in general you will want to pass either the entire contents as a single string, or a list of lines that already have line endings.
Rewrites the existing text file. The provided subroutine is called for each line, and must return everything that should be written back. The sub can return undef to essentially skip (remove) a line.
A lock file is used, so external processes should not depend on the individual files being flocked.
Using a text editor while revbank is running and changing files will still mess things up.
The locking mechanism provides a lock per process; different parts (e.g. plugins) of the same process can still simultaneously do things, so keep to the pattern of always closing files before returning control or forking.