Ir al contenido

Configurar stores y coordinar regeneraciones

La elección del store determina dónde se comparte la caché y qué significa un lock.

StorePersistencia y alcanceCoordinación
memorySolo esta instancia/proceso; se pierde al reiniciarRedLock sobre el mismo backend; no coordina workers.
fileJSON en un directorio local compartidoEscrituras con locks de archivo y reemplazo; cache.lock() solo coordina el mismo loop y directorio.
redisServicio Redis configuradoLease RedLock de aiocache; no es una transacción de negocio.
memcachedServicio Memcached, sujeto a evictionLease RedLock con las garantías del backend.
databaseTablas en una conexión OrionisFilas únicas y leases; requiere constraints únicos efectivos.

El manager acepta los nombres integrados memory, file, redis, memcached y database; no ofrece un registro extend() de stores nombrados. Para un backend propio puedes construir CacheRepository(backend, prefix) con la API aiocache utilizada por el repositorio, o reemplazar ICacheManager mediante el contenedor. La propiedad driver de una entidad store no selecciona arbitrariamente otra implementación.

Los stores serializan con JSON de msgspec: limita el contrato de tus valores a estructuras JSON y verifica round trips si necesitas fechas, tuplas o tipos propios. El Serializer enriquecido documentado en artefactos no participa en estos stores. Una fecha puede volver como texto y una tupla como lista; no presupongas identidad de tipos.

El store database crea sus tablas de entradas y locks de forma lazy; la conexión necesita permisos de creación. Rechaza conexiones sin restricciones únicas efectivas, como Redshift. No depende de que ejecutes una migración de caché específica. Mantén los nombres de tablas exclusivos de la aplicación. El store file usa expiraciones basadas en reloj monotónico; no lo uses como persistencia duradera ni compartas sus archivos entre máquinas con relojes monotónicos distintos.

remember() por sí solo puede ejecutar varios resolvers para la misma ausencia. Adquiere un lock y vuelve a comprobar dentro de la sección antes de calcular. El significado de timeout cambia según store: en file limita la espera para adquirir; en database sirve además como lease; en RedLock es la duración del lease. La expiración del lease no cancela tu código y puede permitir otro escritor mientras aún estás dentro.

Usa locks de caché para reducir trabajo duplicado. Para invariantes de saldo, inventario o unicidad, utiliza transacciones o constraints en el sistema persistente. No se incluye renovación automática de leases ni fencing tokens.

Este programa independiente en memoria vuelve a comprobar la caché dentro del lock mediante remember(). En la aplicación, sustituye build_summary por una lectura o cálculo async que devuelva datos regenerables.

import asyncio
from orionis.cache import CacheRepository
from orionis.cache.stores.memory import build
async def build_summary() -> dict:
return {"published_products": 42}
async def main() -> None:
cache = CacheRepository(build())
async with cache.lock("catalog:v1:rebuild", timeout=2):
summary = await cache.remember("catalog:v1", 60, build_summary)
print(summary) # {'published_products': 42}
asyncio.run(main())

Memory usa el RedLock de aiocache, basado en una reserva temporal, y solo coordina usuarios de la misma instancia. Sirve para reducir cálculos duplicados; no protege saldos ni inventario. Elige un backend compartido cuando varios procesos necesiten el resultado y considera los límites del lease descritos arriba.

ClaveVariable de entornoValor predeterminado
cache.defaultCACHE_STOREfile
cache.prefixCACHE_PREFIXvacío
cache.stores.file.pathCACHE_FILE_PATHstorage/framework/cache/data
cache.stores.redis.endpoint/port/db/passwordREDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD127.0.0.1, 6379, 0, None
cache.stores.memcached.endpoint/portMEMCACHED_HOST, MEMCACHED_PORT127.0.0.1, 11211
cache.stores.database.connectionDB_CACHE_CONNECTIONconexión DB predeterminada
cache.stores.database.tableDB_CACHE_TABLEcache
cache.stores.database.lock_tableDB_CACHE_LOCK_TABLEcache_locks

Las rutas file relativas se resuelven contra app.basePath. Las entidades validan nombres de driver y opciones durante la preparación.

El BootstrapCache incluido usa prefijo vacío; la entidad base Cache usa orionis cuando se construye directamente sin override. Verifica qué configuración crea tu aplicación.

CacheProvider es diferible: el contenedor registra el manager singleton cuando se necesita ICacheManager y después fija la fachada Cache. El store database obtiene su conexión mediante ConnectionResolver. Los stores file y database serializan mediante JSON de msgspec.

El paquete también se usa en compilación del framework y otros módulos con estado almacenado. Importar orionis.cache no construye un backend ni conecta un servicio.

  • Ausencia y None almacenado son indistinguibles mediante get, pero remember los distingue internamente.
  • clear() vacía el namespace del backend y no filtra por prefijo.
  • pull es lectura seguida de eliminación, no una primitiva backend atómica.
  • Misses concurrentes de remember pueden ejecutar varias veces el resolver.
  • Stores inválidos o no configurados lanzan CacheStoreException; pueden propagarse errores de conexión, serializer y backend.
  • add convierte el ValueError de duplicado en False; no suprime excepciones no relacionadas.
  • Locks file/database con timeout finito pueden lanzar TimeoutError. El lease puede expirar durante una sección crítica larga.
  • FileBasedCache.save solo acepta diccionarios y actualiza su hash con un intervalo interno corto (0,5 segundos).

La creación de repositorios es diferida y se almacena por manager. Memory es local al proceso; file desplaza operaciones bloqueantes y usa file locks/reemplazo atómico; Redis y Memcached delegan a aiocache; database asegura su esquema de forma diferida y usa operaciones DB para coordinación compartida.

Los locks async de file se comparten solo dentro del mismo event loop y directorio. Database hace polling cada 0,05 segundos y usa lease predeterminado de 10 segundos sin timeout. Los demás backends usan RedLock con lease predeterminado de 10 segundos. Los métodos por lotes delegan a multi-operaciones del backend.

Usa from orionis.support.facades.cache import Cache en una aplicación iniciada. CacheProvider registra ICacheManager como singleton y fija la fachada. store(name=None) es síncrono y devuelve un repositorio; los demás métodos delegan al store predeterminado:

from orionis.support.facades import Cache
async def cache_example() -> None:
repo = Cache.store("redis")
value = await repo.get("key")
await repo.set("key", value, ttl=60)

Los nombres soportados son file, memory, redis, memcached y database. Un store desconocido o ausente provoca CacheStoreException.

ICacheManager, ICacheRepository e IFileBasedCache definen contratos sustituibles. Backends personalizados entregados a CacheRepository deben proporcionar los métodos estilo aiocache utilizados (get, set, exists, delete, lotes, add e increment).

Referencia de implementación para extensiones

Sección titulada «Referencia de implementación para extensiones»
ÁreaResponsabilidad
cache_manager.py, provider.pyConstrucción/reutilización de stores, proxy predeterminado y registro de fachada/contenedor.
repository.pyOperaciones async uniformes y prefijos.
stores/Backends memory, file, Redis, Memcached y database.
locks/Context manager async adaptado al backend.
serializer.py, serializers/Codificación enriquecida compatible con JSON y serializer aiocache.
file_based_cache.pyCaché de un archivo invalidada por hash de fuentes.
contracts/, exceptions.pyInterfaces de extensión y errores.

Índice · database · orm