Skip to content

ProcessPool with fork context triggers unexpected parent process shutdown on task timeout (v5.2.0) #159

Description

@aircloud

Description:
I am experiencing an issue where the parent process (running a Quart/Hypercorn web server) unexpectedly enters a shutdown sequence whenever a task in the ProcessPool reaches its timeout. This behavior started after upgrading to v5.2.0 and specifically occurs when using the fork multiprocessing context.

Environment:

  • Pebble Version: 5.2.0
  • Python Version: 3.8+
  • OS: Linux

Multiprocessing Context: fork

Steps to Reproduce:

  1. Create a ProcessPool with context=multiprocessing.get_context("fork").

  2. Schedule a long-running task with a short timeout (e.g., 15s).

  3. Use pebble.asynchronous.process or a manual bridge to asyncio.

  4. Observe that when the TimeoutError is raised, the parent process receives a signal (likely SIGTERM) and triggers its own shutdown hooks (@app.after_serving in Quart).

Analysis:
Based on the logs and call stacks, when a timeout occurs, PoolManager.update_tasks calls self.worker_manager.maybe_stop_worker(task.worker_id), which eventually invokes stop_process(worker).

In a fork environment, the worker process belongs to the same Process Group as the parent. It appears that the signal sent to terminate the worker is either leaking to the parent process or being treated as a group-wide signal, causing the parent (web server) to initiate its graceful shutdown sequence.

Proposed Fix/Question:
Should pebble explicitly ensure that signals sent during maybe_stop_worker are scoped strictly to the child PID, or should it automatically call os.setpgrp() in forked workers to isolate them from the parent's signal group?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions