Skip to content

Fix Windows serve without signal support#92

Merged
samdark merged 1 commit into
masterfrom
issue-87-windows-serve
Jul 6, 2026
Merged

Fix Windows serve without signal support#92
samdark merged 1 commit into
masterfrom
issue-87-windows-serve

Conversation

@samdark

@samdark samdark commented Jul 5, 2026

Copy link
Copy Markdown
Member

Summary

  • add serve runtime capability checks for PCNTL, POSIX signal constants, and Windows separators
  • skip prefork workers and ReactPHP signal handlers when the runtime cannot support them
  • document Windows single-process serve behavior and mark the roadmap item complete

Closes #87.

Tests

  • make test -- --filter ServeRuntimeCapabilitiesTest
  • make test -- --filter ServeCommandTest
  • make test
  • make build-docs
  • make psalm
  • make composer-dependency-analyser

Summary by CodeRabbit

  • New Features

    • serve now adapts automatically to platform capabilities, supporting Windows with a single server process while using prefork workers where available.
  • Bug Fixes

    • Improved server behavior on systems without POSIX signal support, avoiding unsupported worker and signal handling paths.
  • Documentation

    • Updated serving and preview docs to clarify platform-specific behavior and worker settings.

Copilot AI review requested due to automatic review settings July 5, 2026 08:14
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a ServeRuntimeCapabilities class that detects PCNTL/POSIX signal support at runtime, wires it into ServeCommand to conditionally enable worker-pool forking and SIGINT/SIGTERM event-loop handlers, adds unit tests, and updates documentation and roadmap to describe Windows single-process behavior.

Changes

Runtime capability detection and serve wiring

Layer / File(s) Summary
Capability detection class
src/Console/ServeRuntimeCapabilities.php
New final readonly class detects SIGINT/SIGTERM constants and pcntl_*/posix_kill function availability, exposing supportsEventLoopSignals() and supportsWorkerPool() with overridable constructor parameters.
ServeCommand integration
src/Console/ServeCommand.php
Constructor now injects ServeRuntimeCapabilities; worker-pool activation replaces function_exists('pcntl_fork') with supportsWorkerPool(), and SIGINT/SIGTERM handler registration becomes conditional on supportsEventLoopSignals().
Capability detection tests
tests/Unit/Console/ServeRuntimeCapabilitiesTest.php
New PHPUnit test class validates supportsWorkerPool()/supportsEventLoopSignals() across Windows-like, POSIX, and partial-support configurations.
Docs and roadmap updates
docs/binaries-phar-docker.md, docs/commands.md, docs/preview.md, roadmap.md
Documentation clarifies that preforking and POSIX signal handling apply only on PCNTL/signal-capable platforms, with Windows running a single server process; roadmap notes Windows-compatible serve as completed.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ServeCommand
  participant ServeRuntimeCapabilities
  participant EventLoop

  User->>ServeCommand: run serve command
  ServeCommand->>ServeRuntimeCapabilities: supportsWorkerPool()
  ServeRuntimeCapabilities-->>ServeCommand: true/false
  alt supportsWorkerPool true
    ServeCommand->>ServeCommand: fork worker pool
  else false
    ServeCommand->>ServeCommand: run single server process
  end
  ServeCommand->>ServeRuntimeCapabilities: supportsEventLoopSignals()
  ServeRuntimeCapabilities-->>ServeCommand: true/false
  alt supportsEventLoopSignals true
    ServeCommand->>EventLoop: register SIGINT/SIGTERM handlers
  end
Loading

Related issues: #87 (yiipress serve fails on Windows due to undefined SIGINT/PCNTL usage)

Suggested labels: windows, bug, enhancement

Suggested reviewers: samdark, vjik

🐰 A rabbit hops through PCNTL's maze,
On Windows now it finds safer ways,
No SIGINT crash, no forked despair,
One process serves with gentle care.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing Windows serve behavior without signal support.
Linked Issues check ✅ Passed The code avoids PCNTL and SIGINT/SIGTERM handlers when unsupported, which addresses issue #87's Windows failure.
Out of Scope Changes check ✅ Passed The docs, tests, and roadmap update are all directly tied to the Windows serve fix and runtime capability checks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-87-windows-serve

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes yiipress serve on Windows by detecting missing PCNTL/signal support at runtime and conditionally disabling prefork workers and ReactPHP signal handlers, preventing crashes like “Undefined constant SIGINT”. It also updates documentation and marks the roadmap item as complete.

Changes:

  • Introduce ServeRuntimeCapabilities to centralize runtime feature checks (PCNTL, POSIX signals, Windows separators).
  • Gate prefork worker mode and event-loop signal hooks in ServeCommand behind capability checks.
  • Add unit tests and update docs/roadmap to reflect Windows single-process behavior.

Reviewed changes

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

Show a summary per file
File Description
tests/Unit/Console/ServeRuntimeCapabilitiesTest.php Adds unit coverage for capability combinations (Windows-like, missing signal constants, missing PCNTL pieces).
src/Console/ServeRuntimeCapabilities.php New runtime capability helper used to decide whether to enable signals and worker pool.
src/Console/ServeCommand.php Uses runtime capabilities to avoid SIGINT/SIGTERM and prefork logic on unsupported runtimes.
roadmap.md Marks the Windows-compatible serve roadmap item as completed.
docs/preview.md Documents Windows single-process preview behavior and conditional use of workers/signals.
docs/commands.md Clarifies --workers behavior on POSIX vs Windows/unsupported runtimes.
docs/binaries-phar-docker.md Updates packaging/runtime docs to describe single-process Windows behavior and conditional preforking.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/Unit/Console/ServeRuntimeCapabilitiesTest.php (1)

14-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test isolating the directorySeparator check in supportsWorkerPool().

This test combines directorySeparator: '\\' with sigintDefined: false / sigtermDefined: false. Since supportsEventLoopSignals() already returns false from the signal flags alone, supportsWorkerPool() returns false regardless of the directory-separator branch — the actual $this->directorySeparator !== '\\' short-circuit (the core Windows-detection logic this PR introduces) is never exercised in isolation.

As per coding guidelines, **/*Test.php: "For each piece of code add a test using phpunit."

✅ Suggested additional test
#[Test]
public function windowsDirectorySeparatorAloneDisablesWorkerPool(): void
{
    $capabilities = new ServeRuntimeCapabilities(
        directorySeparator: '\\',
        sigintDefined: true,
        sigtermDefined: true,
        pcntlAsyncSignalsAvailable: true,
        pcntlForkAvailable: true,
        pcntlSignalDispatchAvailable: true,
        pcntlSignalAvailable: true,
        pcntlWaitAvailable: true,
        pcntlWaitStatusAvailable: true,
        posixKillAvailable: true,
    );

    self::assertFalse($capabilities->supportsWorkerPool());
    self::assertTrue($capabilities->supportsEventLoopSignals());
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Unit/Console/ServeRuntimeCapabilitiesTest.php` around lines 14 - 31,
Add a focused PHPUnit test for ServeRuntimeCapabilities::supportsWorkerPool()
that isolates the directorySeparator check by keeping the signal flags enabled
while setting directorySeparator to '\\'. The current
windowsRuntimeDoesNotSupportWorkerPoolOrEventLoopSignals() test also disables
event-loop signals, so it does not prove the Windows short-circuit in
supportsWorkerPool(). Create a new test in ServeRuntimeCapabilitiesTest that
asserts supportsWorkerPool() is false solely because of the Windows directory
separator, and verify supportsEventLoopSignals() remains true in that setup.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/Unit/Console/ServeRuntimeCapabilitiesTest.php`:
- Around line 14-31: Add a focused PHPUnit test for
ServeRuntimeCapabilities::supportsWorkerPool() that isolates the
directorySeparator check by keeping the signal flags enabled while setting
directorySeparator to '\\'. The current
windowsRuntimeDoesNotSupportWorkerPoolOrEventLoopSignals() test also disables
event-loop signals, so it does not prove the Windows short-circuit in
supportsWorkerPool(). Create a new test in ServeRuntimeCapabilitiesTest that
asserts supportsWorkerPool() is false solely because of the Windows directory
separator, and verify supportsEventLoopSignals() remains true in that setup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1bcd25c-f364-4feb-aff7-8f5f4e52442f

📥 Commits

Reviewing files that changed from the base of the PR and between 3d1d078 and e264d4a.

📒 Files selected for processing (7)
  • docs/binaries-phar-docker.md
  • docs/commands.md
  • docs/preview.md
  • roadmap.md
  • src/Console/ServeCommand.php
  • src/Console/ServeRuntimeCapabilities.php
  • tests/Unit/Console/ServeRuntimeCapabilitiesTest.php

@samdark samdark merged commit 41cd5dd into master Jul 6, 2026
9 checks passed
@samdark samdark deleted the issue-87-windows-serve branch July 6, 2026 07:22
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.

yiipress serve on Windows doesn't work

2 participants