Skip to content

0.17.0 - The Cluster Strikes Back

Choose a tag to compare

@chrisguidry chrisguidry released this 22 Jan 16:24
· 142 commits to main since this release
97620f8

This is a big one!

We finally have Redis cluster support thanks to some initial research and exploration by @zzstoatzz, who helped me realize that we could in fact do it! Point your Docket to a redis+cluster://... or rediss+cluster:// URL and everything should just work 🙏.

Second, we have a new kind of dependency function called a Shared dependency, and the idea is that these are shared across all your tasks for the lifespan of the Worker. Think FastAPI lifespan functions, but you declare them on your tasks instead of separately outside of them. It looks like this:

from contextlib import asynccontextmanager

from docket import Depends, Shared, task


async def load_config():
    """Worker-scoped: loaded once at startup, same config for all tasks."""
    return await fetch_config_from_vault()


@asynccontextmanager
async def db_pool():
    """Worker-scoped: created once, shared by all tasks, closed at shutdown."""
    pool = await create_pool("postgresql://...")
    yield pool
    await pool.close()


@asynccontextmanager
async def db_connection(pool: Pool = Shared(db_pool)):
    """Task-scoped: fresh connection per task, returned to pool after."""
    async with pool.connection() as conn:
        yield conn


@task
async def process_order(
    order_id: int,
    db: Connection = Depends(db_connection),
    config: Config = Shared(load_config),
):
    await db.execute(
        "UPDATE orders SET status = $1 WHERE id = $2",
        config.default_status,
        order_id,
    )

Big thanks to @omikader for the feature request and brainstorming that brought us to this.

What's Changed

Full Changelog: 0.16.6...0.17.0