<@ULVA73B9P> Although `prefect.events.emit_event` ...
# ask-marvin
u
@Marvin Although
prefect.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.
m
thought for 317.4 seconds
Short answer: yes—explicitly drain the EventsWorker before your process exits. In Prefect 3.x,
prefect.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:
Copy code
from prefect.events.worker import EventsWorker

# After your last emit_event call, before the function returns
EventsWorker.instance().drain()
Example for AWS Lambda:
Copy code
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:
Copy code
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).