Skip to main content

Asyncio

The worker that ships today is threaded — it runs jobs on a thread pool and your handlers are ordinary synchronous functions. Because Python releases the GIL on I/O, I/O-bound handlers already run concurrently, and heartbeating while a job runs is straightforward.

An asyncio-native worker (async def handlers running as tasks on the event loop) is a planned fast-follow, not part of the current release.

What to do until then

The threaded worker covers the large majority of background-job workloads. If your handler code is async, you have two good options today:

  • Run the async work from a sync handler. Drive a coroutine to completion inside the handler:

    import asyncio
    from zeridion_flare.worker import FlareWorker, JobContext

    worker = FlareWorker()

    @worker.job("FetchAndStore")
    def fetch_and_store(payload, ctx: JobContext) -> None:
    asyncio.run(_do_async_work(payload, ctx))

    async def _do_async_work(payload, ctx):
    ...
  • Keep handlers synchronous. For most jobs, synchronous I/O on a pool thread is simpler and performs well.

Why threaded first

A threaded worker reuses the synchronous HTTP client and lets a handler block without stalling the rest of the worker — the heartbeat for a running job keeps its own cadence on a separate thread. The async worker adds true per-task cancellation on top of this once it lands.

If a native async worker is important for your stack, let us know through the project's issue tracker so it can be prioritized.

See also