Skip to content

Add --reuse-port option to the server for horizontal scaling - #4

Merged
martinhanzik merged 6 commits into
mainfrom
202606_emssa_reuseport
Jun 3, 2026
Merged

Add --reuse-port option to the server for horizontal scaling#4
martinhanzik merged 6 commits into
mainfrom
202606_emssa_reuseport

Conversation

@messa

@messa messa commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds support for running multiple server instances behind the same address for horizontal scaling.

  • New --reuse-port CLI option (also configurable as reuse_port: true in the YAML config) sets SO_REUSEPORT. With it, multiple server instances can listen on the same host:port and the kernel load-balances incoming connections across them — useful since a single server instance is single-threaded. In Docker, run the instances with --network=host.
  • If --reuse-port is requested on a platform without SO_REUSEPORT, the server fails fast with a clear ConfigurationError message (consistent with the other configuration validation errors) instead of an opaque socket error.
  • SO_REUSEADDR is left to asyncio's per-platform default (enabled on POSIX, not on Windows/Cygwin), so the socket behavior stays safe on every platform.
  • Server creation was extracted from async_main into create_server(conf) to make the binding behavior directly testable.
  • The README documents the scaling approach, including the SO_REUSEPORT same-effective-user requirement.

Tests

  • test_configuration.py — unit tests for the reuse_port config plumbing (CLI and YAML).
  • test_reuse_port_subprocess.py — behavioral tests that start the server as a subprocess: two instances bind together with --reuse-port, and a second instance fails to bind without it (skipped on platforms without SO_REUSEPORT). Readiness is detected from the server's Listening on ... log line (event-driven), so the tests don't rely on fixed sleeps.
  • test_smoke.py — added a --help smoke test for the server.

All 19 server tests pass locally (~0.2s).

🤖 Generated with Claude Code

The server socket now always sets SO_REUSEADDR explicitly (asyncio already
enables it on Unix by default) and can optionally set SO_REUSEPORT via the
new --reuse-port CLI option, also configurable as reuse_port in the YAML
config. With SO_REUSEPORT multiple server instances can listen on the same
address and the kernel load-balances connections across them, letting the
otherwise single-threaded server use more CPU cores (e.g. in Docker with
--network=host).

Server creation was extracted into create_server() to make it testable.
Tests cover both the configuration plumbing and the actual two-instance
binding behavior, and the scaling approach is documented in the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a --reuse-port / reuse_port: true option to enable SO_REUSEPORT so multiple server processes can bind the same host:port and let the kernel distribute incoming connections, plus tests and documentation for the behavior.

Changes:

  • Added --reuse-port CLI flag and reuse_port YAML config plumbing.
  • Refactored server startup into create_server(conf) and extended socket bind options.
  • Added smoke/config/subprocess tests and documented horizontal scaling in README.md.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
server/logline_server/main.py Adds --reuse-port flag and refactors server creation/binding behavior.
server/logline_server/configuration.py Adds reuse_port config parsing from CLI/YAML.
server/tests/test_configuration.py Unit tests for reuse_port config behavior.
server/tests/test_reuse_port_subprocess.py Subprocess behavioral tests for binding with/without --reuse-port.
server/tests/test_smoke.py Smoke test ensuring python -m logline_server --help works.
README.md Documents how to scale the server using --reuse-port.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/logline_server/main.py Outdated
Comment thread server/logline_server/configuration.py
messa and others added 3 commits June 2, 2026 14:31
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The reuse-port subprocess tests now react to the server's "Listening on ..."
log line (via a ServerProcess wrapper that drains stderr in a background
thread) rather than waiting a fixed amount of time to infer success. This
makes the positive test assert directly that both instances bound, turns the
checks event-driven, and cuts the suite runtime from ~2.2s to ~0.2s.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Passing reuse_address=True unconditionally also enabled SO_REUSEADDR on
Windows, where it has different semantics and would let another socket
hijack an address that is already actively in use. asyncio already enables
SO_REUSEADDR by default only on POSIX (not on Windows/Cygwin), so dropping
the explicit flag keeps the safe behavior on every platform.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@messa

messa commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Toto asi pak bude lepší squashnout, mít commity jednotlivě nepřidá do projektou žádnou hodnotu navíc.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Comment thread server/logline_server/main.py Outdated
Comment thread server/logline_server/main.py Outdated
Comment thread server/logline_server/configuration.py
Comment thread server/tests/test_reuse_port_subprocess.py
Comment thread README.md
messa and others added 2 commits June 2, 2026 17:01
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@messa
messa requested a review from martinhanzik June 2, 2026 15:08
@messa messa self-assigned this Jun 2, 2026
@martinhanzik
martinhanzik merged commit c0e43e6 into main Jun 3, 2026
22 checks passed
@martinhanzik
martinhanzik deleted the 202606_emssa_reuseport branch June 3, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants