Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Dec 8, 2025

Summary

When PHP acquires file locks via flock(), the locks are managed at the kernel level per-process. Multiple PHP WASM instances within the same OS process would share those locks, defeating the purpose of file locking for concurrent access control.

This PR ensures CLI workers use exactly one PHP instance by:

  • Adding maxPhpInstances option to PHPRequestHandler that, when set to 1, bypasses PHPProcessManager entirely and uses a single PHP instance directly
  • Refactoring the spawn handler into a unified createPhpSpawnHandler() that accepts a configurable phpCliHandler for subprocess spawning
  • CLI workers now use createPhpSpawnHandler without a PHP CLI handler, meaning proc_open('php ...') returns exit code 127 instead of spawning in-process
  • Web environments continue using sandboxedSpawnHandlerFactory which spawns PHP instances via PHPProcessManager

New Spawn Handler API

// Core handler - works everywhere
createPhpSpawnHandler({
  getPrimaryPhp: () => Promise<PHP>,  // For ls, pwd commands
  phpCliHandler?: PHPCliHandler,       // Optional: handles php commands
})

// Helper for multi-instance mode (web)
createProcessManagerCliHandler(acquirePHPInstance)

// Legacy wrapper - auto-detects mode based on processManager presence
sandboxedSpawnHandlerFactory(requestHandler)

Test plan

  • TypeScript compiles without errors
  • Lint passes
  • sandboxedSpawnHandlerFactory tests pass
  • Manual test: CLI worker handles HTTP requests correctly
  • Manual test: proc_open('ls') works in CLI
  • Manual test: proc_open('php ...') returns exit code 127 in CLI

@adamziel adamziel marked this pull request as draft December 8, 2025 20:57
@adamziel adamziel force-pushed the max-1-php-instance-per-cli-worker branch 2 times, most recently from c912ca0 to 26d9d7b Compare December 8, 2025 21:37
When PHP acquires file locks via flock(), the locks are managed at the kernel
level per-process. Multiple PHP WASM instances within the same OS process would
share those locks, defeating the purpose of file locking for concurrent access
control.

This change ensures CLI workers use exactly one PHP instance by:

- Adding maxPhpInstances option to PHPRequestHandler that, when set to 1,
  bypasses PHPProcessManager entirely and uses a single PHP instance
- Refactoring spawn handler into a unified createPhpSpawnHandler() that accepts
  a configurable phpCliHandler for subprocess spawning
- CLI workers now use createPhpSpawnHandler without a PHP CLI handler, meaning
  proc_open('php ...') returns exit code 127 instead of spawning in-process
- Web environments continue using sandboxedSpawnHandlerFactory which spawns
  PHP instances via PHPProcessManager

The spawn handler API is now:
- createPhpSpawnHandler({ getPrimaryPhp, phpCliHandler? }) - core handler
- createProcessManagerCliHandler(acquirePHPInstance) - for multi-instance mode
- sandboxedSpawnHandlerFactory(requestHandler) - legacy wrapper
@adamziel adamziel force-pushed the max-1-php-instance-per-cli-worker branch from 26d9d7b to 56a4aef Compare December 8, 2025 21:46
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.

2 participants