i have a shutdown_callback method that triggers at...
# ask-ai
c
i have a shutdown_callback method that triggers at call end. and i also have a livekit-egress webhook. What is the flow of execution of both of these. Which will trigger first.
✅ 1
t
Thanks for reaching out, Kushagra. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — you're asking which runs first: your agent's
shutdown_callback
at call end, or the LiveKit
livekit-egress
webhook. The
shutdown_callback
runs first (it executes inside your agent when the session shuts down). The
livekit-egress
webhook (for example
egress_ended
) is sent later by the LiveKit server once the recording/egress process fully finishes. The webhook delivery is independent of your agent process and can arrive seconds after your shutdown callback completes. If you need guaranteed ordering for any post-processing, would you prefer guidance on coordinating them (e.g., having the shutdown callback wait for an egress status or handling idempotent webhook processing)? Sources: Job lifecycle | LiveKit Documentation | Backup Egress Recordings, with interactive elements
c
yes, i need the shutdown callback to wait
t
Got it — you want the
shutdown_callback
to wait for the egress webhook (
egress_ended
) before finishing. That isn’t automatic, but you can coordinate them. Two patterns: • Preferred: Have your webhook handler signal completion and only run final shutdown work from there. a. Webhook receives
egress_ended
→ mark session egress complete (DB flag, cache, or in-memory store). b. Webhook then invokes your cleanup logic (or triggers the agent shutdown flow) so ordering is guaranteed. • Alternative: Have the
shutdown_callback
wait for the webhook signal. a. Webhook handler sets a shared flag/DB record or releases an async event when
egress_ended
arrives. b. In your
shutdown_callback
, poll or await that flag/event before proceeding. c. Ensure the shutdown timeout is long enough (default is 10s); increase
shutdown_process_timeout
if needed. Minimal example (conceptual):
Copy code
# shared place: in-memory or persistent store keyed by session_id
egress_done = EventStore()

# webhook handler
def handle_egress_webhook(payload):
    session_id = payload["session_id"]
    egress_done.set(session_id)

# shutdown callback
async def shutdown_hook(ctx):
    session_id = ctx.session_id
    await egress_done.wait(session_id, timeout=30)  # wait for webhook signal
    await do_cleanup()
Notes: • Use a persistent store (DB or Redis) if webhook and agent run on different machines/processes. • Make your cleanup idempotent in case of retries or race conditions. • If you control the webhook endpoint, have it return success only after your cleanup has been triggered/queued to reduce race windows. Which pattern fits your architecture — letting the webhook trigger cleanup, or having the shutdown hook wait? Tell me whether webhook and agent run on the same host/process and I’ll give code tailored to your stack. Sources: Job lifecycle | LiveKit Documentation | Why is my Agent insights data missing? | LiveKit, with interactive elements