Ns cache

From AOLserver Wiki
Revision as of 04:29, 27 October 2009 by Akhassin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

NAME

ns_cache − Cache arbitrary data

SYNOPSIS

ns_cache append cachename key string ?string ...?
ns_cache create cachename ?-size maxsize? ?-timeout timeout? ?-maxwait maxwait?
ns_cache eval cachename key script
ns_cache flush cachename key
ns_cache get cachename key ?varname?
ns_cache incr cachename key ?value?
ns_cache lappend cachename key string ?string ...?
ns_cache names cachename ?pattern?
ns_cache set cachename key string

DESCRIPTION

AOLserver implements a C API for caching arbitrary data. A cache, in this context, is simply a dictionary that maps keys to values. Keys are always stored as NUL-terminated strings. How values are stored depends on the type of cache. In past versions of AOLserver, an addon module called nscache provided a Tcl API on top of the C API to allow storing arbitrary strings. In AOLserver 4.5.1, ns_cache is now a builtin command which is syntax-compatible with the nscache module but is implemented differently and has several important behavioral differences:
  • The module supported thread-specific, virtual-server-specific and serverwide (i.e. process-wide) caches, with virtual-server-specific as the default. AOLserver 4.5.1's builtin ns_cache allows but ignores -thread and -serverwide switches and always creates serverwide caches shared by all virtual servers.
  • In AOLserver 4.5.1, all caches are size-limited whether -size is specified or not (if omitted, maxsize defaults to 1 Megabyte (1024*1000 bytes)) plus can optionally have a timeout.
  • In AOLserver 4.5.1, the timeout is not really a sliding window timeout from last access like it was in the nscache module. It's really a fixed maximum lifetime from last update after which an entry expires and is no longer used.
  • The new built-in ns_cache get does not wait for a concurrent ns_cache eval to execute its script, instead it behaves as if the cache entry does not exist (ns_cache set and incr throw an "entry busy: ..." error if there is a concurrent ns_cache eval for the same key).
  • Instead it is now ns_cache eval that waits on another concurrent ns_cache eval for the same key but only up to the maxwait defined for the cache as a whole at creation time (defaults to 2 seconds) and then throws a "timeout waiting for update: ..." error. The default of 2 seconds can easily be exceeded by an expensive database operation the result of which you want to cache.
  • append and lappend are new options (they also throw an "entry busy" error if a concurrent ns_cache eval is executing)


ns_cache create cachename ?-size maxsize? ?-timeout timeout? ?-maxwait maxwait?
This command creates a new global process-wide cache named cachename limited to 1 Megabyte by default or the number of bytes specified in maxsize. If timeout is given, entries will be considered expired after the specified number of seconds from the last update and will no longer be used. The -maxwait parameter is new to the AOLserver 4.5.1 implementation and provides a maximum wait in seconds that ns_cache eval will wait for another ns_cache eval for the same key to run its script and update the cache before throwing an error. The default maxwait is 2 seconds.
This command returns nothing if it is successful.
ns_cache eval cachename key script
This command atomically sets and gets a cache value. First, it looks up key in the cache named cachename. If it finds an unexpired entry, it returns the value of that entry. Otherwise, it executes script, stores the return value in the cache, and also returns that value.
Note that ns_cache eval detects concurrent evals for the same key and waits for the other ns_cache eval to execute its script and update the cache but only up to the maxwait defined for the cache as a whole at creation time (defaults to 2 seconds) and then throws a "timeout waiting for update: ..." error..
Script may optionally use the return command to return its value. For example, this will store the value "2" in mycache, if mykey is not already present:
ns_cache eval mycache mykey { expr {1+1} }
This will also store the value "2" in mycache:
ns_cache eval mycache mykey { return [expr {1+1}] }
If script raises an error, or exits with break or continue, then ns_cache eval simply returns the same condition without modifying the cache.
ns_cache flush cachename key ?key? ?key? ...
This command removes the entry for key from the cache named cachename. If the cache has no entry for key or the key is in progress of being created by a concurrent ns_cache eval, then nothing happens.
The ability to specify multiple key names is new in the AOLserver 4.5.1 builtin ns_cache, it was not present in the nscache module. All keys are flushed in a single atomic/locked operation. This command returns nothing.
Note that there is also an ns_cache_flush command that can flush the entire cache.
ns_cache get cachename key ?varname?
This command looks up key in the specified cache. It operates differently depending on whether varname was given.
If varname absent and the key exists and is unexpired, the value is returned and if the key is missing or expired an error is raised. If varname is provided and the key exists and is unexpired the command sets varname to the value and returns 1, otherwise it returns 0.
ns_cache names cachename ?pattern?
This command returns a list of all unexpired, fully-built keys currently in the specified cache. If pattern is specified, only matching entries are returned (match pattern syntax like in string match).
Note that there is also an ns_cache_keys command which pretty much does the same thing, except that command will include keys that have expired but have not yet been flushed and keys that are still in progress of being built by ns_cache eval.
ns_cache set cachename key value
This command stores value for key in the specified cache.


CACHE DETAILS

Entries in the global cache are accessible to all threads. Each cache has its own SINGLE mutex that protects access to ALL its entries.
Cache values are stored as counted strings, so arbitrary binary data can be cached. A global cache stores strings instead of Tcl objects to prevent race conditions that could lead to heap corruption.
The cache has a maximum size specified when the cache is created. The size of the cache is the sum of the sizes of all the values in the cache; keys do not count toward a cache's size. If inserting a value into the cache makes the size of the cache exceed its maximum, then cache entries are evicted starting with the least-recently used entry until the size is below the maximum size (or until only the new value remains in the cache).
If -timeout is specified when the cache is created, the entries in this cache will have a maximum lifetime and will be considered expired after the specified number of seconds. Currently there is no way to set this expiration on an individual key but this should be a fairly small change. Note that this is different from the nscache module, where timeout was a sliding window from last access. This is in fact a strict expiration from last update such as exists in ns_adp_include -cache, for example. Expired entries are lazy-flushed upon access, however, when a cache has to be purged due to exceeding its size, expired entries are not treated any differently from unexpired ones.

SEE ALSO

nsv

Category Documentation - Category Core Tcl API