Library interface — oslo.cache — branch stable/2026.2
Branch
stable/2026.2@fc96999a99e4(4.3.0+ 3 commits) — repository https://opendev.org/openstack/oslo.cache — analysed on 2026-10-28
oslo.cache exposes no service. It is a thin layer over dogpile.cache (1.5.0 in the analysed environment) that OpenStack services use to:
- build a dogpile cache region from the
[cache]section of their configuration; - memoize functions, with a per-group switch and TTL.
Everything that travels to memcached or Redis is decided by dogpile.cache and the client library, configured by oslo.cache. 03 describes that traffic, and 07 the contract a Go service must respect to share it.
1. Public API
The package exports 5 names (oslo_cache/__init__.py):
| Name | Purpose | Reference |
|---|---|---|
configure(conf) | registers the [cache] options on a ConfigOpts | oslo_cache/core.py:651-662 |
create_region(function=…) | creates an unconfigured dogpile region; the key generator defaults to dogpile's function_key_generator | oslo_cache/core.py:434-456 |
configure_cache_region(conf, region) | configures the region from [cache], once | oslo_cache/core.py:459-513 |
get_memoization_decorator(conf, region, group, expiration_group=None) | memoization decorator, switched by [<group>] caching and timed by [<group>] cache_time | oslo_cache/core.py:577-648 |
NO_VALUE | dogpile's "no value" marker (miss or expired) | oslo_cache/core.py:68 |
Other entry points used by services:
oslo_cache.testing.CacheIsolatingProxy: proxy that deep-copies values for the in-memory test backend (oslo_cache/testing.py:52-76);- the deprecated
function_key_generatorandkwarg_function_key_generatorwrappers, which only call dogpile's (oslo_cache/core.py:408-431); - private but imported by keystonemiddleware:
oslo_cache._memcache_pool.MemcacheClientPoolandoslo_cache._bmemcache_pool.BMemcacheClientPool, used by the auth_token token cache (keystonemiddleware:keystonemiddleware/auth_token/_cache.py:105-110). Renaming them breaks keystonemiddleware.
2. Configuring a region
configure_cache_region (oslo_cache/core.py:459-513):
- refuses anything that is not a dogpile
CacheRegion(ConfigurationError,oslo_cache/core.py:478-481); - does nothing if the region is already configured;
- builds a flat dictionary
<config_prefix>.backend,<config_prefix>.expiration_time,<config_prefix>.arguments.*with_build_cache_config(oslo_cache/core.py:130-389), and gives it to dogpile'sconfigure_from_config; - wraps the backend with
_DebugProxyifdebug_cache_backendis set: every get, set and delete is logged with its key and value (oslo_cache/core.py:74-120); - installs the SHA-1 key mangler if the backend has none (
oslo_cache/core.py:498-499); - wraps the backend with each class listed in
proxies.
From [cache] to backend arguments
_build_cache_config (oslo_cache/core.py:130-389). The 17 cases recorded in _rewrite/config-mapping_stable-2026.2.json show its output.
| Rule | Reference |
|---|---|
The backend is dogpile.cache.null unless enabled = true: the configured backend is then used | oslo_cache/core.py:137-139 |
expiration_time (600) becomes the region's expiration time | oslo_cache/core.py:140 |
Each backend_argument name:value becomes an argument. For dogpile.cache.memcached and oslo_cache.memcache_pool, url is split on commas. A value without : is logged and ignored | oslo_cache/core.py:141-169 |
Redis and Redis Sentinel: username, password, socket_timeout, db; host/port from redis_server (port 6379 by default), or service_name and sentinels (host:port list) | oslo_cache/core.py:171-193 |
Every other backend gets the memcache arguments: url = memcache_servers (unless a backend_argument already set it), socket_timeout, username, password, and the memcache_* options without their prefix (dead_retry, pool_maxsize, pool_unused_timeout, pool_connection_get_timeout, pool_flush_on_reconnect, sasl_enabled) | oslo_cache/core.py:194-238 |
backend_expiration_time: must be ≥ expiration_time. It becomes memcached_expire_time (memcached backends) or redis_expiration_time (Redis). Any other backend is refused | oslo_cache/core.py:240-266 |
tls_enabled: an ssl.SSLContext (tls_cafile, tls_certfile/tls_keyfile, tls_allowed_ciphers) for pymemcache and memcache_pool; connection_kwargs (and sentinel_kwargs) for Redis. Any other backend is refused | oslo_cache/core.py:268-321 |
enable_socket_keepalive: pymemcache KeepaliveOpts, or Redis TCP keepalive options. Any other backend is refused | oslo_cache/core.py:330-359 |
enable_retry_client: pymemcache only; passes the 5 retry_*/hashclient_* options | oslo_cache/core.py:366-387 |
The pooled memcached backend oslo_cache.memcache_pool
PooledMemcachedBackend (oslo_cache/backends/memcache_pool.py:48-107) is dogpile's python-memcached backend, but each call borrows a client from a pool (ClientProxy, oslo_cache/backends/memcache_pool.py:36-45):
- pool: at most
memcache_pool_maxsize(10) clients; an idle client is closed aftermemcache_pool_unused_timeout(60 s); waiting for a client is limited tomemcache_pool_connection_get_timeout(10 s), thenQueueEmptyis raised (oslo_cache/_memcache_pool.py:179-201); - dead servers: a client that finds a dead server reports it to the pool, which marks it dead for every client for
memcache_dead_retry(300 s) (oslo_cache/_memcache_pool.py:285-321); - TLS or SASL: the pool switches to python-binary-memcached (
BMemcacheClientPool, memcached binary protocol,oslo_cache/_bmemcache_pool.py:65-89). SASL withoutusernameandpasswordis refused (oslo_cache/backends/memcache_pool.py:70-82).
Other backends provided: oslo_cache.dict (in-process dictionary, oslo_cache/backends/dictionary.py:29-111) and oslo_cache.etcd3gw (etcd v3 through its HTTP gateway, values as JSON, oslo_cache/backends/etcd3gw.py:30-81).
3. Memoization
get_memoization_decorator (oslo_cache/core.py:577-648) returns region.cache_on_arguments(should_cache_fn=…, expiration_time=…):
- cache or not: the value is stored only if
[cache] enabledand[<group>] caching(defaultTrueif the option does not exist) (oslo_cache/core.py:536-541). The cache is still read whencaching = false(scenario 8 of 07); - TTL:
[<expiration_group>] cache_timeif set, otherwise[cache] expiration_time(oslo_cache/core.py:569-572). It is read at each call, so a change of configuration applies without restart; - key: dogpile's
function_key_generator,<module>:<function name>|<arguments separated by spaces>.self/clsare dropped, and keyword arguments are refused. Through the decorator, default values are included:get_project("p1")gives…:get_project|p1 default. The key then goes through the SHA-1 mangler. - The decorator carries
should_cacheandget_expiration_time, to pre-fill the cache (oslo_cache/core.py:642-646).
4. Options ([cache], oslo_cache/_opts.py:34-412)
| Option | Default | Notes |
|---|---|---|
config_prefix | cache.oslo | prefix of the dogpile configuration keys |
expiration_time | 600 | seconds; checked by the reader, not by the server (07 § 3) |
backend_expiration_time | none | server-side TTL; ≥ expiration_time |
backend | dogpile.cache.null | 13 choices: oslo_cache.memcache_pool, oslo_cache.dict, oslo_cache.etcd3gw, dogpile.cache.{pymemcache, memcached, pylibmc, bmemcached, dbm, redis, redis_sentinel, memory, memory_pickle, null} (oslo_cache/_opts.py:70-98) |
backend_argument | [] | secret; name:value |
proxies | [] | classes wrapping the backend |
enabled | False | global switch |
debug_cache_backend | False | logs keys and values |
memcache_servers | localhost:11211 | |
memcache_dead_retry | 300 | |
memcache_pool_maxsize, memcache_pool_unused_timeout, memcache_pool_connection_get_timeout | 10, 60, 10 | memcache_pool only |
memcache_pool_flush_on_reconnect | False | |
memcache_sasl_enabled | False | binary protocol |
redis_server, redis_db, redis_sentinels, redis_sentinel_service_name | localhost:6379, 0, localhost:26379, mymaster | |
username, password | none | password is secret |
tls_enabled, tls_cafile, tls_certfile, tls_keyfile, tls_allowed_ciphers | False, none… | |
socket_timeout | 1.0 | formerly memcache_socket_timeout / redis_socket_timeout |
enable_socket_keepalive, socket_keepalive_idle/interval/count | False, 1, 1, 1 | |
enable_retry_client, retry_attempts, retry_delay, hashclient_retry_attempts, hashclient_retry_timeout, hashclient_dead_timeout | False, 2, 0, 2, 1, 60 | pymemcache only |
Source: reverse-spec-oslo.cache/01-library-interface_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.