Background Cleanup¶
psycache ignores expired keys when reading, but their rows stick around until something deletes them.
You can call PostgresCache.cleanup_expired() yourself, or let psycache do it for you in the background.
A cleanup thread¶
For synchronous pools, PostgresCache.start_cleanup_thread() starts a daemon thread that periodically deletes expired entries.
Use it as a context manager to stop the thread automatically:
from sqlalchemy import create_engine
from psycache import PostgresCache
from psycache.sqlalchemy import SQLAlchemyCachePool
engine = create_engine("postgresql+psycopg://psycache@127.0.0.1/psycache")
cache = PostgresCache(SQLAlchemyCachePool(engine))
with cache.start_cleanup_thread(interval=60):
... # your application runs here
Or manage its lifecycle manually through the returned CleanupService:
svc = cache.start_cleanup_thread(interval=60)
try:
... # your application runs here
finally:
svc.stop()
engine.dispose()
… or a cleanup task¶
For async pools, use AsyncPostgresCache.start_cleanup_task() inside a running event loop.
It starts an asyncio.Task that periodically deletes expired entries and can be used as an async context manager.
Otherwise, it mirrors the behavior of PostgresCache.start_cleanup_thread():
import asyncio
from sqlalchemy.ext.asyncio import create_async_engine
from psycache import AsyncPostgresCache
from psycache.sqlalchemy import AsyncSQLAlchemyCachePool
aengine = create_async_engine("postgresql+psycopg://psycache@127.0.0.1/psycache")
acache = AsyncPostgresCache(AsyncSQLAlchemyCachePool(aengine))
async def main():
async with acache.start_cleanup_task(interval=60):
... # your application runs here
svc = acache.start_cleanup_task(interval=60)
try:
... # your application runs here
finally:
await svc.stop()
asyncio.run(main())