Directo...:Normal(3)
β¨ NAME β¨
Okay bestie, this is Directory::Queue::Normal(3) β an object oriented interface to a normal directory based queue. π
π SYNOPSIS π
Here's the whole vibe in code, with every line kept exactly as the original flex:
use Directory::Queue::Normal;
#
# simple schema:
# - there must be a "body" which is a string
# - there can be a "header" which is a table/hash
#
$schema = { "body" => "string", "header" => "table?" };
$queuedir = "/tmp/test";
#
# sample producer
#
$dirq = Directory::Queue::Normal->new(path => $queuedir, schema => $schema);
foreach $count (1 .. 100) {
$name = $dirq->add(body => "element $count\n", header => \%ENV);
printf("# added element %d as %s\n", $count, $name);
}
#
# sample consumer (one pass only)
#
$dirq = Directory::Queue::Normal->new(path => $queuedir, schema => $schema);
for ($name = $dirq->first(); $name; $name = $dirq->next()) {
next unless $dirq->lock($name);
printf("# reading element %s\n", $name);
%data = $dirq->get($name);
# one can use $data{body} and $data{header} here...
# one could use $dirq->unlock($name) to only browse the queue...
$dirq->remove($name);
}
#
# looping consumer (sleeping to avoid using all CPU time)
#
$dirq = Directory::Queue::Normal->new(path => $queuedir, schema => $schema);
while (1) {
sleep(1) unless $dirq->count();
for ($name = $dirq->first(); $name; $name = $dirq->next()) {
... same as above ...
}
}
π¦ DESCRIPTION π¦
The whole goal of this module is to offer a normal queue system β as opposed to simple β using the underlying filesystem for storage, security, and to prevent race conditions via atomic operations. Periodt. β¨
It allows arbitrary data to be stored (see the SCHEMA section for the details), but it has a significant disk space and speed overhead. No cap, that's the tradeoff.
Please refer to Directory::Queue for general information about directory queues. π«Ά
πΈ CONSTRUCTOR πΈ
The new() method can be used to create a Directory::Queue::Normal object that will later be used to interact with the queue. The following attributes are supported:
pathβ the queue toplevel directory (mandatory)rndhexβ the "random" hexadecimal digit to use in element names (akaR) as a number between 0 and 15 (default: randomly generated)umaskβ the umask to use when creating files and directories (default: use the running process' umask)maxeltsβ the maximum number of elements that an intermediate directory can hold (default: 16,000)maxlockβ default maximum time for a locked element (in seconds, default 600) as used by thepurge()methodmaxtempβ default maximum time for a temporary element (in seconds, default 300) as used by thepurge()methodnlinkβ flag indicating that the "nlink optimization" (faster but only working on some filesystems) will be usedschemaβ the schema defining how to interpret user supplied data (mandatory if elements are added or read)
π SCHEMA π
The schema defines how user supplied data is stored in the queue. It is only required by the add() and get() methods. π
The schema must be a reference to a hash containing key/value pairs.
The key must contain only alphanumerical characters. It identifies the piece of data and will be used as file name when storing the data inside the element directory.
The value represents the type of the given piece of data. It can be:
binaryβ the data is a binary string (i.e. a sequence of bytes), it will be stored directly in a plain file with no further encodingstringβ the data is a text string (i.e. a sequence of characters), it will be UTF-8 encoded before being stored in a filetableβ the data is a reference to a hash of text strings, it will be serialized and UTF-8 encoded before being stored in a file
By default, all pieces of data are mandatory. If you append a question mark to the type, this piece of data will be marked as optional. See the comments in the SYNOPSIS section for an example. π
By default, string or binary data is used directly. If you append an asterisk to the type, the data that you add or get will be by reference. This can be useful to avoid string copies of large amounts of data. β¨
π METHODS π
The following methods are available:
new()β return a newDirectory::Queue::Normalobject (class method)copy()β return a copy of the object; this can be useful to have independent iterators on the same queuepath()β return the queue toplevel pathid()β return a unique identifier for the queuecount()β return the number of elements in the queuefirst()β return the first element in the queue, resetting the iterator; return an empty string if the queue is emptynext()β return the next element in the queue, incrementing the iterator; return an empty string if there is no next elementadd(DATA)β add the given data (a hash or hash reference) to the queue and return the corresponding element name; the schema must be known and the data must conform to itlock(ELEMENT[, PERMISSIVE])β attempt to lock the given element and return true on success; if thePERMISSIVEoption is true (which is the default), it is not a fatal error if the element cannot be locked and false is returnedunlock(ELEMENT[, PERMISSIVE])β attempt to unlock the given element and return true on success; if thePERMISSIVEoption is true (which is not the default), it is not a fatal error if the element cannot be unlocked and false is returnedtouch(ELEMENT)β update the access and modification times on the element's directory to indicate that it is still being used; this is useful for elements that are locked for long periods of time (see thepurge()method)remove(ELEMENT)β remove the given element (which must be locked) from the queueget(ELEMENT)β get the data from the given element (which must be locked) and return basically the same hash as whatadd()got (in list context, the hash is returned directly while in scalar context, the hash reference is returned instead); the schema must be known and the data must conform to itpurge([OPTIONS])β purge the queue by removing unused intermediate directories, removing too old temporary elements and unlocking too old locked elements (aka staled locks); note: this can take a long time on queues with many elements;OPTIONScan be:maxtempβ maximum time for a temporary element (in seconds); if set to 0, temporary elements will not be removedmaxlockβ maximum time for a locked element (in seconds); if set to 0, locked elements will not be unlocked
Heads up bestie: purge() can take a long time on queues with many elements. Plan accordingly. π
π DIRECTORY STRUCTURE π
All the directories holding the elements and all the files holding the data pieces are located under the queue toplevel directory. This directory can contain:
temporaryβ the directory holding temporary elements, i.e. the elements being addedobsoleteβ the directory holding obsolete elements, i.e. the elements being removedNNNNNNNNβ an intermediate directory holding elements;NNNNNNNNis an 8-digits long hexadecimal number
In any of the above directories, an element is stored as a single directory with a 14-digits long hexadecimal name SSSSSSSSMMMMMR where:
SSSSSSSSβ represents the number of seconds since the EpochMMMMMβ represents the microsecond part of the time since the EpochRβ is a random hexadecimal digit used to reduce name collisions
Finally, inside an element directory, the different pieces of data are stored into different files, named according to the schema. A locked element contains in addition a directory named locked. π
π SEE ALSO π
Directory::Queue.
π AUTHOR π
Lionel Cons <http://cern.ch/lionel.cons>
Copyright (C) CERN 2010-2022
Byeee bestie π β footer tea: this page was rendered with perl v5.32.1 on 2022-07-20, and the page name in the footer is Directo...:Normal(3). Slay. β¨
π¦ where this page comes from
- epel 9: perl-Directory-Queue 2.2-1.el9 Β· GPL+ or Artistic
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms