def METHOD_NAME() -> Generator[asyncio.AbstractEventLoop, None, None]:
    """Run an event loop in a worker thread.
    Entering this context manager spawns a thread, starts an asyncio event loop in it,
    and returns that loop.
    Exiting this context manager stops and cleans up the event loop, and then joins the thread.
    """
    loop_mailbox: "queue.SimpleQueue[asyncio.AbstractEventLoop]" = queue.SimpleQueue()
    def _in_thread() -> None:
        loop = asyncio.new_event_loop()
        # We assume that the lines above this will never fail,
        # so we will always reach this point to unblock the parent thread.
        loop_mailbox.put(loop)
        loop.run_forever()
        # If we've reached here, the loop has been stopped from outside this thread. Clean it up.
        #
        # This cleanup is naive because asyncio makes it difficult and confusing to get it right.
        # Compare this with asyncio.run()'s cleanup, which:
        #
        # * Cancels and awaits any remaining tasks
        #   (according to the source code--this seems undocumented)
        # * Shuts down asynchronous generators
        #   (see asyncio.shutdown_asyncgens())
        # * Shuts down the default thread pool executor
        #   (see https://bugs.python.org/issue34037 and asyncio.shutdown_default_executor())
        #
        # In Python >=3.11, we should rewrite this to use asyncio.Runner,
        # which can take care of these nuances for us.
        loop.close()
    thread = Thread(
        target=_in_thread,
        name=f"{__name__} event loop thread",
        # This is a load-bearing daemon=True. It avoids @atexit-related deadlocks when this is used
        # by opentrons.execute and cleaned up by opentrons.execute's @atexit handler.
        # https://github.com/Opentrons/opentrons/pull/12970#issuecomment-1648243785
        daemon=True,
    )
    thread.start()
    loop_in_thread = loop_mailbox.get()
    try:
        yield loop_in_thread
    finally:
        loop_in_thread.call_soon_threadsafe(loop_in_thread.stop)
        thread.join()