Skip to content

Fix AttributeError on Windows when terminating worker on hard timeout - #471

Merged
auvipy merged 4 commits into
celery:mainfrom
0xrutabaga:fix/issue-375-windows-hard-timeout
Oct 13, 2026
Merged

auvipy merged 4 commits into
celery:mainfrom
0xrutabaga:fix/issue-375-windows-hard-timeout

Conversation

@0xrutabaga

Copy link
Copy Markdown
Contributor

Fixes #375.

Problem

On Windows, \os.getpgid\ and \os.killpg\ are not implemented. During hard timeout in \TimeoutHandler._trywaitkill(process), calling \os.getpgid(worker.pid) == worker.pid\ raises \AttributeError: module 'os' has no attribute 'getpgid', crashing the \TimeoutHandler\ thread.

Solution

  • Check \hasattr(os, 'getpgid')\ and \hasattr(os, 'killpg')\ before calling \os.getpgid\ and \os.killpg.
  • On platforms lacking these functions (such as Windows), fall back directly to \worker.terminate()\ and _kill(worker.pid, SIGKILL)\ (which invokes \kill_processtree\ on Windows).
  • Add unit tests verifying \TimeoutHandler._trywaitkill\ gracefully handles platforms lacking \os.getpgid\ / \os.killpg.

Verification

  • Verified \ /unit/test_pool.py::test_pool::test_hard_timeout_does_not_stall_pool\ passes on Windows without thread crash (previously failed with \AttributeError).
  • Added unit tests in \ /unit/test_pool.py\ testing _trywaitkill\ when \os.getpgid\ and \os.killpg\ are absent.

@auvipy
auvipy self-requested a review October 7, 2026 02:57
@auvipy auvipy added the Bug Fix label Oct 12, 2026

@auvipy auvipy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got this from the issue comment:

I believe if the OS is Windows then you should skip the first if statement and go directly to the else. Windows does not support getpgid.

Adding a sys.platform != "win32" as the first check in line 702 and 713 seems to fix the issue.

Follow reviewer feedback to check sys.platform != 'win32' before entering POSIX process group branch in TimeoutHandler._trywaitkill, while retaining capability checks for non-Windows platforms. Expand unit test suite covering Windows behavior, escalation, POSIX group and non-group leaders, missing POSIX functions, and OSError suppression.
@0xrutabaga

Copy link
Copy Markdown
Contributor Author

Thank you for the review and suggestion @auvipy!

I have updated the PR to explicitly check sys.platform != 'win32' as the first guard in both the SIGTERM and SIGKILL escalation branches in TimeoutHandler._trywaitkill, while retaining the hasattr checks so non-Windows environments lacking process-group capabilities remain protected.

In addition, I expanded the unit test suite in /unit/test_pool.py to cover:

  • Windows platform termination and escalation to _kill(worker.pid, SIGKILL)
  • POSIX process-group leader kill (os.killpg for both SIGTERM and SIGKILL)
  • POSIX non-group leader fallback to worker.terminate()
  • Fallback when os.getpgid or os.killpg are missing on non-Windows platforms
  • OSError handling and suppression during termination races

All unit tests pass on Windows (119 passed, 15 skipped).

@auvipy
auvipy merged commit 531c3ae into celery:main Oct 13, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hard Timeout Triggers AttributeError on Windows

2 participants