Description
The rq-janitor process crashes every 10 seconds on the native Windows build (v2.1.4) with:
AttributeError: module 'signal' has no attribute 'SIGALRM'. Did you mean: 'SIGABRT'?
The traceback shows RQ's timeouts.py:setup_death_penalty() calling signal.SIGALRM, which does not exist on Windows (it's POSIX-only). This happens whenever the janitor tries to clean up a failed/timed-out job.
Root Cause
In windows/launcher.py, the codebase already patches several POSIX-only os functions for Windows compatibility:
if not hasattr(_os_patch, 'wait4'): ...
if not hasattr(_os_patch, 'WIFEXITED'): ...
if not hasattr(_os_patch, 'WIFSIGNALED'): ...
if not hasattr(_os_patch, 'WTERMSIG'): ...
if not hasattr(_os_patch, 'WEXITSTATUS'): ...
But it misses signal.SIGALRM. RQ's rq/timeouts.py:setup_death_penalty() uses signal.alarm() (which requires signal.SIGALRM) for job timeouts. When a job times out, the janitor tries to execute the failure callback, which calls setup_death_penalty(), which crashes because SIGALRM does not exist.
Impact
- The janitor enters an infinite error loop, logging the full traceback every 10 seconds
- Stale/timed-out jobs can never be cleaned up
- Log file fills rapidly (~8640 lines/day of identical errors)
- Does not block actual work — the workers (
rq-worker-default, rq-worker-high) function correctly. Only the cleanup path is broken.
Suggested Fix
Add a signal.SIGALRM monkey-patch in windows/launcher.py alongside the existing os patches:
import signal as _signal_patch
if not hasattr(_signal_patch, 'SIGALRM'):
_signal_patch.SIGALRM = 0
_signal_patch.alarm = lambda seconds: None
This prevents RQ's timeout code from crashing. Jobs won't get auto-killed on timeout (since signal.alarm becomes a no-op), but the janitor can at least clean up the job registry without crashing.
Alternatively, patch RQ's setup_death_penalty directly to use a threading-based timer on Windows instead of signals.
Reproduction
- Install AudioMuse-AI v2.1.4 native on Windows 10/11
- Set AUDIOMUSE_PLATFORM=windows in setup wizard
- Run analysis or clustering until a job times out
- Observe rq-janitor logs filling with SIGALRM errors every 10 seconds
Environment
- AudioMuse-AI v2.1.4 (native Windows, amd64)
- Windows 11, Intel i7-14700K
- Embedded PostgreSQL (port 65272) + Redis
Description
The
rq-janitorprocess crashes every 10 seconds on the native Windows build (v2.1.4) with:The traceback shows RQ's
timeouts.py:setup_death_penalty()callingsignal.SIGALRM, which does not exist on Windows (it's POSIX-only). This happens whenever the janitor tries to clean up a failed/timed-out job.Root Cause
In
windows/launcher.py, the codebase already patches several POSIX-onlyosfunctions for Windows compatibility:But it misses
signal.SIGALRM. RQ'srq/timeouts.py:setup_death_penalty()usessignal.alarm()(which requiressignal.SIGALRM) for job timeouts. When a job times out, the janitor tries to execute the failure callback, which callssetup_death_penalty(), which crashes becauseSIGALRMdoes not exist.Impact
rq-worker-default,rq-worker-high) function correctly. Only the cleanup path is broken.Suggested Fix
Add a
signal.SIGALRMmonkey-patch inwindows/launcher.pyalongside the existingospatches:This prevents RQ's timeout code from crashing. Jobs won't get auto-killed on timeout (since
signal.alarmbecomes a no-op), but the janitor can at least clean up the job registry without crashing.Alternatively, patch RQ's
setup_death_penaltydirectly to use a threading-based timer on Windows instead of signals.Reproduction
Environment