3 Commits

Author SHA1 Message Date
Benoit Chesneau
2d03d8e6a9 tests: Add signal handling and liveness tests for gthread worker
Add tests for:
- Worker liveness reporting to arbiter via WorkerTmp
- SIGTERM graceful shutdown behavior
- SIGQUIT immediate shutdown behavior
- Worker-arbiter integration (parent death detection, timeout)
- Signal interaction edge cases (multiple signals, ordering)

These tests ensure the gthread worker properly:
- Calls notify() in the main loop for arbiter heartbeat
- Handles SIGTERM by setting alive=False and waking the poller
- Handles SIGQUIT by immediately shutting down the thread pool
- Drains connections during graceful shutdown within timeout
- Cleans up resources properly on exit
2026-01-22 09:54:04 +01:00
Benoit Chesneau
0186211400 gthread: Lock-free PollableMethodQueue refactoring
Replace RLock-based synchronization with a pipe-based method queue
for lock-free coordination between worker threads and main thread.

Key changes:
- Add PollableMethodQueue class using os.pipe() for wake-up signaling
- Non-blocking pipe (both ends) for BSD compatibility (FreeBSD, OpenBSD)
- Unified event loop using single poller.select() - no more futures.wait()
- Better graceful shutdown with connection draining within grace period
- Rename _keep to keepalived_conns, remove _lock entirely
- Add handle_exit() for SIGTERM, improve handle_quit() for SIGQUIT
- Add set_accept_enabled() for dynamic connection acceptance control
- Add wait_for_and_dispatch_events() with EINTR handling

Performance improvement: ~8% at high concurrency due to reduced
lock contention and non-blocking pipe operations.

Tests: 40 tests covering PollableMethodQueue, graceful shutdown,
keepalive management, error handling, and BSD compatibility.

Fixes #3146
Closes #3157
2026-01-22 09:32:48 +01:00
Benoit Chesneau
b43dc6d398 gthread: Improve reliability and fix edge cases
This commit addresses three issues with the gthread worker:

1. Request body handling on keepalive
   - Add finish_body() method to Parser to discard unread body bytes
   - Call it before returning connections to the poller
   - Prevents socket appearing readable due to leftover body
   Fixes #3301

2. Timeout reliability with monotonic clock
   - Replace time.time() with time.monotonic() in set_timeout()
   - Replace time.time() with time.monotonic() in murder_keepalived()
   - Prevents timeout issues caused by NTP adjustments

3. SSL error handling
   - Move conn.init() from enqueue_req() to handle()
   - SSL handshake now runs in worker thread, not main thread
   - ENOTCONN errors during ssl_wrap_socket are caught per-connection
   - Prevents entire worker crashes on SSL handshake failures

Also adds comprehensive unit tests for the gthread worker.

Closes #3303
Closes #3308
2026-01-22 09:14:19 +01:00