Skip to content

Idle worker doesn't stop on SIGTERM without uvloop #722

Open

Description

@AlexeyShalaev

On the default asyncio loop (no uvloop), a worker that is idle waiting for a message doesn't react to SIGTERM. The process manager forwards the signal, the worker logs Got signal 2., and then it keeps waiting until it gets killed, so broker.shutdown() and the shutdown events never run.

interrupt_handler in taskiq/cli/worker/run.py is registered with signal.signal and calls shutdown_event.set(). That only queues the event's waiters on the loop and doesn't wake it. A loop with no timers stays in epoll_wait until some I/O arrives. uvloop handles signals differently, which is why this only shows up without it.

Repro on taskiq 0.13.0, Python 3.12, no uvloop, with a broker whose listen() just waits on a pipe nobody writes to:

import asyncio, os
from taskiq import AsyncBroker

class IdleBroker(AsyncBroker):
    async def kick(self, message):
        pass

    async def listen(self):
        r, _ = os.pipe()
        loop = asyncio.get_running_loop()
        fut = loop.create_future()
        loop.add_reader(r, fut.set_result, None)
        await fut
        yield b""

broker = IdleBroker()

taskiq worker idlebroker:broker --workers 1, then kill -TERM the main process: the worker is still running 15 s later. Same with taskiq-redis ListQueueBroker against a real Redis with socket_timeout=None: still running 20 s after SIGTERM.

Calling loop.call_soon_threadsafe(shutdown_event.set) in the handler instead (with the loop created before the handlers are installed) makes the worker shut down right away in both cases, and broker.shutdown() runs.

This may be what #63 is about. I can send a PR with that change and a test if you'd like.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions