ExSite::Store

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 (typically %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 (concurrent, or subsequent) 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. Furthermore, those classes should also clean out stale entries in the store if the original source data is updated.

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.

Storage Keys

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. The simplest way to accomplish this is to use an MD5 hash of all the relevant key data. For example, if caching the results of a SQL query, create an MD5 hash of the entire query string,or alternatively of the parameters to the appropriate fetch function that builds the query. It is the responsibility of the caller to use appropriately hashed keys, as the store does not know or care about the origin of the data.

The store records a few internal statistics under plain text keys that are prefixed with ``_''.

Storage Lifetime

Every item has a limited lifetime in the store. It will expire if not accessed within a certain time period (by default, $config{store}{max_idle}, which is normally 1 hour). Little-used items will be dropped from the store relatively quickly by this mechanism. Even frequently-used items will expire after a maximum storage period has elapsed (by default, this is $config{store}{max_lifetime}, which is normally 1 day). When an item expires, it is deleted from the store, and would then have to be regenerated and re-stored by higher levels of code.

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.

The default lifetimes of a stored item are defined in $config{store}{max_idle} and $config{store}{max_lifetime}. You can override these values for invididual stored items using the the special _store method, eg:

    my $s = tie %store, "ExSite::Store";
    $s->_store($key,$value,$my_lifetime,$my_idletime);

or, alternatively,

    (tied %store)->_store($key,$value,$my_lifetime,$my_idletime);

Storage Limits

To keep the store from blowing up, there is a maximum size of an object that can be persistently stored. This is defined in $config{store}{max_size}, which defaults to 10K. Attempts to store larger objects will be ignored.

Storage Engine

The ExSite::Store class handles the general-purpose store logic. Low-level storage happens in the storage engine, which can be one of the following:

DBM
The engine is a DBM disk file, which is essentially a high-performance disk-based hash.

SHM
The engine is a Sys-V shared memory segment.

none
There is no storage engine, and items placed in the store will not persist beyond the current process. This is the default.

DBM should be a bit slower, in principle, than SHM, since it uses disk rather than memory. In actual practice, however, DBM benefits from filesystem caching that is performed by the kernel, and is often comparable in speed to SHM. Otherwise, the advantage of DBM is that data will persist even through a full reboot of the server.

If you run multiple installations of ExSite on a server, you should take care to separate the stores for each of them. If using DBM, this should take no special effort, since the store files are written to the local directory, which should be separated anyway. When using SHM, however, you will have to give each installation a distinct shared memory ID ($config{store}{shmid}).

Statistics

The store keeps track of the hits (items found successfully), misses (requested items that were not found), deletes (removed expired items), saves (items stored), and connections to the store.

These can be reported using the special summary method, as follows:

    my $s = tie %store, "ExSite::Store";
    print $s->summary;

This will also summarize all objects currently in the store, by listing their keys and sizes.

Special Methods

The following special methods can be accessed from the store object itself:

make
Creates the storage engine, if it does not exist. In some cases (creating DBM files, in particular) this must be done as a privileged user, since the web server generally does not have the necessary privileges to write to disk.

remove
Removes the storage engine entirely. This may also require more priveleges than the web server normally has.

reset
Clears the storage engine of all data.