ExSite::Store is a multi-purpose data store that allows for sharing of complex data structures among different processes. It is used by ExSite for the following purposes:
Furthermore, any plug-in module can utilize the Store for persistent storage of data.
The data store exposes itself to the application as a simple hash
(%store
) which may be used by any code in a read/write
fashion. Values written to %store
will persist beyond the life of
the process, and will be available to other processes to read.
It is assumed that the store will be accessed via wrapper classes that will handle the job of fetching data from original sources, loading the data into the store, and checking the store for the data before returning to the original source. See for example, ExSite::Cache and ExSite::Session. Those classes are responsible for specifying any special timeouts for stored values, otherwise the default expiry timeout is used (typically 1 hour).
The values written to the store can be arbitrarily complex Perl data
structures. They are serialized using Storable::freeze
before being
saved, and are recovered using Storable::thaw
. Freezing and thawing
of stored values is handled automatically by the store.
Since the store can keep track of widely disparate data, it is important to use unique keys when reading or writing to it, to avoid grabbing or overwriting unrelated data accidentally. However, the store does not police this in any way, so you can easily clobber your own data if not careful. If in doubt, use a standard prefix on your keys (eg. your plug-in name) to keep them in an identifiable group. For example, the database cache prefixes its store keys with ``cache'': by default, and the session manager prefixes its store keys with ``session:''.
The store records a few internal items under plain text keys that are prefixed with ``_''. Of special importance is the ``_id'' key, which records the ExSite working directory (ie. your CGI-BIN). If this does not match the working directory of the current process, the store connection will be rejected. This is to prevent one site/installation from connecting to another's store.
Every item is placed into the store with an expiry time (which is a Unix timestamp). Items past their expiry time are cleaned out in two cases: (1) if they are fetched after their expiry time, and (2) when garbage collection runs.
The default lifetime of an item placed into the store is defined in the store configuration (see below), and is typically 1 hour. The lifetime can be change/extended by renewing the item:
(tied %store)->renew($key,$new_expiry_time);
You can store an item and set a custom lifetime in one step, as follows:
(tied %store)->put($key,$value,$expiry_time);
If you set the expiry time to 0 using either of these methods, the item will persist in the store indefinitely. Use this for system configurations that are not expected to change during normal system use.
Purging of expired items occurs automatically after a certain amount of time has passed (default is every 15 minutes). This helps to clear out old or infrequently-used items that could use a refresh, or are simply taking up space.
Because the store will remove expired data on a regular basis, you cannot rely on a stored item being present when you request it. Your code is responsible for obtaining the desired data from alternate sources if this is the case. For this reason, the store is useful primarily as a multipurpose cache to improve performance on costly data-fetch operations, or as a place to save state for a limited term.
If you want to extend the lifetime of something in the store, to prevent it from being expired when it is still needed, use the following method:
(tied %store)->renew($key,$new_expiry_time);
The store can be configured to callback to another system component when it automatically clears out expired items. This is so that higher-level components that use the store can clean themselves up if necessary when garbage collection has been done.
If you want to be informed when an item is automatically reaped from the store, register your callback with the store:
(tied %store)->set_callback($my_obj, $notify_method, $regexp);
$my_obj
is the object that should receive the notification.
$notify_method
is the object method that will process the
notification. $regexp
is a regular expression that is used to
match store keys; only matching keys will trigger the notification.
The notification callback method will be passed the key of the expired item. Ie. when an item is expired, the following callback is executed:
$my_obj->$notify_method($key);
Example: When cached items are expired, the cache requires notification so that it can clean up its internal list of cache keys. It registers the callback using something like:
(tied %store)->set_callback($share{Cache}, "delnotify", "^cache:");
Now when the store expires any key starting with ``cache:'', it informs the cache of this by calling:
$share{Cache}->delnotify($key);
This version of the ExSite store uses a GDBM database for persistent storage of data. This is significantly faster than a SQL database, and also has the advantage of persisting on disk even through system reboots, so that sessions and other state data are not lost.
The utility script bin/store.pl
should be used to generate
and initialize the GDBM file. Use this command:
../bin/store.pl --reset
(It will not be automatically generated because the webserver process does not normally have the necessary privileges to create the GDBM files in the working directory.) You can re-run this script to reset the store, but that will clear all stored items from the GDBM file. You should re-run this script if you ever move your CGI-BIN to a different directory (because the store will refuse connection when it detects this), or if you have any problems with file corruption.
Note that DBM files tend to grow as new items are added, but do not shrink when old items are removed. This is because the DBM file holds on to its disk space to reuse it for future items. If the DBM file is taking up too much disk space, you can use this command to shrink the file:
../bin/store.pl --rebuild
The StoreAdm
plug-in supports scheduling of this function at
regular intervals.
The routine Local::store_conf()
contains the configuration
parameters for the store. (These parameters cannot be stored in
%config, because %config is itself read from the store if possible.)
The important configuration settings are:
purge()
is called when the job disconnects from the store
(ie. when the store is untied).
_log
).
.lock
appended.
retry
parameter defines
the maximum number of retries before it gives up and cancels the
operation.
The following special methods can be accessed from the store object itself:
connect()
get($key)
getraw($key)
put($key,$value,$expiry)
$value
) into the store indexed under $key
. An
optional $expiry
time can be provided (Unix timestamp), but the store
default will be used if this is not given.
putraw($key,$store_record)
$value
) into the store indexed under $key
. An
The item should be formatted as a store record, including fields for
the data and expiry time.
delete($key)
$key
.
renew($key,$new_expiry_time)
$key
.
purge()
reset()
rebuild()
size()
summary()
is_persistent()