kash
Caching structures and simplified function memoization
Kash provides implementations of several caching structures as well as a handy macros for defining memoized functions.
Memoized functions defined using #[kash]/#[io_kash]/kash! macros are thread-safe with the backing
function-cache wrapped in a mutex/rwlock, or externally synchronized in the case of #[io_kash].
By default, the cache is not locked for the duration of the function's execution.
So initial concurrent calls (on an empty cache) of long-running functions with the same arguments
will each execute fully, and each overwrites the memoized value as they complete.
To synchronize the execution and caching of not-yet-cached arguments, specify #[kash(sync_writes)]
(not supported by #[io_kash]).
- See
proc_macrofor more procedural macro examples. - See
macrosfor more declarative macro examples.
Features
default: Includeproc_macroandahashfeaturesproc_macro: Include proc macrosahash: Enable the optionalahashhasher as default hashing algorithm.async: Include support for async functions and async cache storesredis_store: Include Redis cache storeredis_async_std: Include async Redis support usingasync-stdandasync-stdtls support, impliesredis_storeandasyncredis_tokio: Include async Redis support usingtokioandtokiotls support, impliesredis_storeandasyncredis_connection_manager: Enable the optionalconnection-managerfeature ofredis. Any async redis caches created will use a connection manager instead of aMultiplexedConnectionredis_ahash: Enable the optionalahashfeature ofredisdisk_store: Include disk cache store
The procedural macros (#[kash], #[io_kash]) offer more features, including async support.
See the proc_macro and macros modules for more samples, and the
examples directory for runnable snippets.
The basic usage looks like:
use kash;
/// Defines a function named `fib` that uses a cache implicitly named `FIB`.
/// By default, the cache will be the function's name in all caps.
/// The following line is equivalent to #[kash(name = "FIB", unbound)]
use sleep;
use Duration;
use kash;
/// Use an explicit cache-type with a custom creation block and custom cache-key generating block
use io_kash;
use AsyncRedisCache;
use Error;
/// Cache the results of an async function in redis. Cache
/// keys will be prefixed with `cache_redis_prefix`.
/// A `map_error` closure must be specified to convert any
/// redis cache errors into the same type of error returned
/// by your function. All `io_kash` functions must return `Result`s.
async
use io_kash;
use DiskCache;
use Error;
/// Cache the results of a function on disk.
/// Cache files will be stored under the system cache dir
/// unless otherwise specified with `disk_dir` or the `create` argument.
/// A `map_error` closure must be specified to convert any
/// disk cache errors into the same type of error returned
/// by your function. All `io_kash` functions must return `Result`s.
Functions defined via macros will have their results kash using the
function's arguments as a key, a convert expression specified on a procedural macros,
or a Key block specified on a kash_key! declarative macro.
When a macro-defined function is called, the function's cache is first checked for an already computed (and still valid) value before evaluating the function body.
Due to the requirements of storing arguments and return values in a global cache:
- Function return types:
- For all store types, except Redis, must be owned and implement
Clone - For the Redis store type, must be owned and implement
serde::Serialize + serde::DeserializeOwned
- For all store types, except Redis, must be owned and implement
- Function arguments:
- For all store types, except Redis, must either be owned and implement
Hash + Eq + Clone, thekash_key!macro is used with aKeyblock specifying key construction, or aconvertexpression is specified on a procedural macro to specify how to construct a key of aHash + Eq + Clonetype. - For the Redis store type, must either be owned and implement
Display, or thekash_key!&Keyor procedural macro &convertexpression used to specify how to construct a key of aDisplaytype.
- For all store types, except Redis, must either be owned and implement
- Arguments and return values will be
clonedin the process of insertion and retrieval. Except for Redis where arguments are formatted intoStringsand values are de/serialized. - Macro-defined functions should not be used to produce side-effectual results!
Thanks
This project is a clone of the awesome https://github.com/jaemk/cached repository
License: MIT