NaviServer - programmable web server
4.99  5.0

[ Main Table Of Contents | Table Of Contents | Keyword Index ]

ns_cache(n) 5.0.0a naviserver "NaviServer Built-In Commands"

Name

ns_cache - Cache manipulation

Table Of Contents

Synopsis

Description

The cache commands store key-value data in memory for quick access, like nsv. Unlike nsv, a limit is placed on the amount of memory used for each cache, and additional limits can be placed on the expire time of cache entries, timeouts waiting for updates, etc.

The cache commands try to be efficient. For example, if two threads are simultaneously accessing the same entry in a cache, and the cache entry does not exist or has expired, then the first thread will evaluate its script to generate the new value. The second thread will recognize this and wait for the first thread to finish, and then return the value computed by the first thread.

A cache will tend to grow to its maximum specified size. Unused entries will move towards the end of the Least Recently Used list and be deleted to make room for new entries. Similarly, expired entries will remain in the cache and only be deleted when they reach the end of the LRU list, or are accessed and it is noticed that they have expired.

OPTIONS

The following options are used for several commands below.

-timeout t

The time to wait for some other thread to compute the cache value. The value t can be specified in the form secs?:microsecs?, or secs.fraction, or as a number with a time unit.

-expires t

A time in the future when the cache entry expires. The expired entry will be deleted only when retrieved, e.g. via ns_cache_eval.

The value t can be specified in the form secs?:microsecs?, or secs.fraction, or as a number with a time unit. Small values of t are treated as offsets, large values as absolute times.

COMMANDS

ns_cache_configure cache ?-timeout time? ?-expires time? ?-maxentry memory-size? ?-maxsize memory-size?

Queries or changes the parameters of a previously created cache. If none of the options are used, the current settings are returned in form of an attribute value list. The values for -maxentry and -maxsize can be specified in memory units (kB, MB, GB, KiB, MiB, GiB).

ns_cache_create ?-timeout time? ?-expires time? ?-maxentry memory-size? ?--? cache size

Creates a new Tcl cache with maximum size size. The size determines the number of entries that can be kept in this particular cache.

The maximum size of a single entry can be specified via the option -maxentry, where the size of an entry is defined by the size of the key plus the size of the value and the internal overhead per cache entry (about 126 bytes on a 64-bit machine). When a value to be stored is arger than -maxentry, it is not cached.

Optionally, a -timeout, an -expires time and -maxentry, the maximum size of a single cache entry value can be specified. The values for size and -maxentry can be specified in memory units (kB, MB, GB, KiB, MiB, GiB).

The function returns 1 when the cache is newly created. When the cache exists already, the function return 0 and leaves the existing cache unmodified.

ns_cache_exists cache

Checks for the existence of a cache and returns 0 (failure) or 1 (success).

ns_cache_names

Returns the list of all caches for the current virtual server.

ns_cache_keys ?-exact? ?--? cache ?pattern?

Returns a list of all keys in the named cache. If pattern is given then each key is matched against the globbing pattern, and only those which match are included in the list. When the option -exact is used, pattern is interpreted literally, either a key with a literally exact match or empty is returned.

ns_cache_eval ?-timeout time? ?-expires time? ?-force? ?--? cache key arg ...

Returns the data identified by key from the named cache. If the key does not exist then provided command is executed. When a single arg is provided, its is interpreted as a script, containing potentially multiple commands. Otherwise it is treated as command name with arguments. The result of he executed call is returned and inserted into the cache.

The script is also executed if a cached value exists but has expired.

If the -force option is set then any existing cached entry is removed whether it has expired or not, and the script is run to regenerate it.

ns_cache_get cache key ?varname?

Returns the cached value for the provided key from the cache. If the optional variable name is not provided, it returns the associated value on success or it raises an error, if the key does not exist. If the optional variable name is provided it returns 1 or 0 on success / failure and sets the provided variable with the associated value (similar to nsv_get).

ns_cache_incr ?-timeout time? ?-expires time? ?--? cache key ?incr?

Increments the integer value in the cache by 1, or by incr if specified, and returns it.

ns_cache_append ?-timeout time? ?-expires time? ?--? cache key arg ...

Appends the given arg ... to the value in the cache and returns the new value. The arg ... and the cache value are treated as simple strings.

If the cache value does not already exist it is created.

ns_cache_lappend ?-timeout time? ?-expires time? ?--? cache key arg ...

Appends the given arg ... to the value in the cache and return the new value. The cache value is as a Tcl list and the arg ... are appended to maintain its well-formed-list format.

If the cache value does not already exist it is created.

ns_cache_flush ?-glob? ?--? cache ?arg ...?

Flushes the entries in a cache and returns the number of flushed entries. If the optional arg ... are given these are used as the keys in the cache to be flushed. If the -glob option is given then the keys are treated as globbing patterns and only the entries with matching keys are flushed.

ns_cache_stats ?-contents? ?-reset? ?--? cache

Returns the accumulated statistics for the given cache in dict format since the cache was created or was last reset.

If the -reset option is given then the statistics will be reset to zero after the command returns.

If the -contents option is given then a list of all entries is returned containing the key, size, hits and expire time for each entry in the cache. The time is in ns_time timespec format. The cache statistics track the following items:

maxsize

The maximum size in bytes this cache can grow to, as specified by the -size option to ns_cache_create.

size

The current size of the cache, in bytes.

entries

The current number of entries the cache contains.

flushed

Number of entries which were explicitly flushed by the ns_cache_flush command.

hits

Number of times cache was queried and entry was present and valid.

missed

Number of times cache was queried and entry was not present or valid.

hitrate

The successful hit rate expressed as a percentage of total hits. Higher is better.

expired

Number of times an entry was found to be present but expired when requested and so not returned.

pruned

Number of times an entry reached the end of the LRU list and was removed to make way for a new entry.

ns_cache_transaction_begin

Begin a cache transaction. A cache transaction provides in essence the ability to rollback the added/updated values, while providing cache isolations to other transactions. The cached values from incomplete cache transactions are just visible from the current thread, but not from other threads. Cache transactions effect always all caches.

Typically, cache transactions are used in accordance with database transactions.

ns_cache_transaction_commit ?-all?

Successfully terminates a cache transaction. All added values are made visible to other threads. The option -all can be used to commit all nested transactions currently open in this thread.

ns_cache_transaction_rollback ?-all?

Terminates a cache transaction and undoes changes in all caches since the matching ns_cache_transaction_begin. The option -all can be used to rollback all nested transactions currently open in this thread.

ns_fastpath_cache_stats ?-contents? ?-reset?

Returns the accumulated statistics for fastpath cache in array-get format since the cache was created or was last reset. For details, see ns_cache_stats above.

Cache Transactions

Background: when ns_cache_* commands are used within a database transaction (e.g. in OpenACS), it might occur, that partial results of the transaction are cached before the transaction is committed. When the transaction is rolled back, invalid values might be kept in the stack leading to erroneous and hard to debug behavior. Furthermore, information about changes might leak into other concurrent threads via the cache, even before the transaction is committed.

The cache transaction semantics is implemented via the three commands:

When no ns_cache_transaction* commands are used, the behavior is exactly as before, the caches are not transactions aware. When cache transactions are used, which are initiated by a ns_cache_transaction_begin call and ended via ns_cache_transaction_commit or ns_cache_transaction_rollback, the ns_cache commands provide in essence the following functionalities:

  1. The ability to rollback of the values since the matching ns_cache_transaction_begin

  2. Isolation of behavior: cached values from incomplete cache transactions are just visible from the current thread, but not from other threads.

  3. Nesting: transactions can be nested (up to a compile time constant, per default: 16)

  4. Introspection: the statistics about cache commits and rollbacks are included in the cache statistics.

Note that the cache transactions span over all defined caches.

EXAMPLES

In the following example our goal is to serve a web page within 5 seconds. The web page requires two sets of data: the user's name and email address, and a personalized advert, both of which are stored in a database.

The data doesn't change often so a cache is used to speed up access. Even so, the server may become so busy that database queries take longer than our target response time of 5 seconds so we specify a -timeout to both calls to the ns_cache_eval command.

In this case, a time 5 seconds into the future is constructed once and passed to both cache calls. The second call will use the remainder of the time once the first completes.

 set timeout [ns_time incr [ns_time get] 5]
 
 if {[catch {
    set user [ns_cache_eval -timeout $timeout -- users $userid {
        db_query {
            select name, email
            from users
            where userid = :userid
        }
    }]
    set ad [ns_cache_eval -timeout $timeout -expires 120 -- ads $userid {
        db_query {
            select advert from
            personalized_adverts
            where userid = :userid
        }
    }]
 } errmsg]} {
    ns_returnunavailable "Sorry, our web server is too busy."
 }
 
 ns_return 200 text/html [example_personalized_page $user $ad]

See Also

ns_memoize, ns_time, ns_urlspace, nsv

Keywords

cache, fastpath, global built-in, server built-in