鹿野孟城
03/17/2026, 1:20 AMprefect.events.emit_event appears to send events to a queue for asynchronous processing by the EventsWorker, is there a way to wait for the queue to finish processing? I am encountering an issue where the process terminates without waiting for event transmission to complete in an AWS Lambda environment.Marvin
03/17/2026, 1:20 AMMarvin
03/17/2026, 1:26 AMprefect.events.emit_event queues the event for asynchronous delivery by the background EventsWorker. In short‑lived environments like AWS Lambda, the process can return before the worker finishes sending. To block until the event queue is sent, call:
from prefect.events.worker import EventsWorker
# After your last emit_event call, before the function returns
EventsWorker.instance().drain()
Example for AWS Lambda:
from prefect.events import emit_event
from prefect.events.worker import EventsWorker
def lambda_handler(event, context):
try:
emit_event(
event="my.custom.event",
resource={"prefect.resource.id": "my-resource"},
)
# ... your work ...
return {"statusCode": 200}
finally:
# Ensure all queued events are transmitted before exit
EventsWorker.instance().drain()
If you prefer a context manager, you can wrap your logic to automatically drain on exit:
from prefect.events import emit_event
from prefect.events.worker import EventsWorker
from prefect._internal.concurrency.services import drain_on_exit
def lambda_handler(event, context):
with drain_on_exit(EventsWorker.instance()):
emit_event(
event="my.custom.event",
resource={"prefect.resource.id": "my-resource"},
)
# ... your work ...
return {"statusCode": 200}
Notes:
- There is no flush() method on an events client; draining the EventsWorker is the supported way to wait for delivery.
- Relying on at-exit hooks is unreliable in Lambda; explicitly draining (as above) is recommended.
- If you are running inside a Prefect flow executed by a long‑lived worker, the engine/workers will typically handle draining on shutdown. In serverless/ephemeral runs, call drain() yourself.
Relevant source references:
- emit_event implementation and public export: prefect/events/utilities.py
- EventsWorker (singleton and queue-backed worker): prefect/events/worker.py
- Drain helpers and context managers: prefect/_internal/concurrency/services.py
If you share a snippet of how you’re invoking Lambda (sync vs async handler, any frameworks), I can tailor the pattern further (e.g., placing drain in a shared teardown path).