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 asynciofrom zeridion_flare.worker import FlareWorker, JobContextworker = 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.