Durable async tasks — retries, caching and more… all observable.
@task(tries=3, timeout=30, cache=True, rate_limit=5) async def crunch(x): return await heavy(x)