Skip to content

Make DispatchContext externally immutable#181

Merged
alganet merged 1 commit intoRespect:masterfrom
alganet:fluent-2
Mar 25, 2026
Merged

Make DispatchContext externally immutable#181
alganet merged 1 commit intoRespect:masterfrom
alganet:fluent-2

Conversation

@alganet
Copy link
Copy Markdown
Member

@alganet alganet commented Mar 25, 2026

DispatchContext:

  • Constructor injection for RoutinePipeline, handlers, and basePath (removes setRoutinePipeline, setHandlers, setPath)
  • All public properties use private(set), readable externally, writable only through internal methods (configureRoute, withRequest)
  • Eliminate transient route mutations in matchRoute/routineMatch
  • Move SplObjectStorage negotiation to request attributes
  • Add handler state reset and error/exception isolation tests

DispatchEngine:

  • Remove $onContextReady closure, no callback coupling
  • Pure stateless dispatcher: creates fully-initialized contexts
  • Expose routinePipeline() getter for Router::createDispatchContext

Router:

  • Remove public $context property and __toString()
  • No per-request state, immutable after route registration

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.35%. Comparing base (4e7f75d) to head (7aaf006).

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #181      +/-   ##
============================================
- Coverage     96.40%   96.35%   -0.05%     
+ Complexity      407      398       -9     
============================================
  Files            31       31              
  Lines          1028     1016      -12     
============================================
- Hits            991      979      -12     
  Misses           37       37              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

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 refactors the router dispatch flow to make DispatchContext externally immutable (no direct property mutation) and to make DispatchEngine stateless with fully-initialized contexts per dispatch, while adding regression tests to ensure handler state (errors/exceptions) does not leak between dispatches.

Changes:

  • Switch DispatchContext to constructor injection for pipeline/handlers/basePath and replace direct mutations with methods like configureRoute() / withRequest().
  • Remove router per-request state (Router::$context, Router::__toString()) and remove DispatchEngine::$onContextReady callback coupling.
  • Move routine negotiation bookkeeping from SplObjectStorage to request attributes; add tests for handler state isolation across dispatches.

Reviewed changes

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

Show a summary per file
File Description
tests/Routines/AuthBasicTest.php Updates test to use configureRoute() instead of mutating $context->route.
tests/RoutinePipelineTest.php Updates route setup to use configureRoute() consistently.
tests/Routes/ExceptionTest.php Adds regression test ensuring exception handler state does not leak between dispatches.
tests/Routes/ErrorTest.php Adds regression test ensuring collected PHP error state does not leak between dispatches.
tests/RouterTest.php Removes reliance on Router::$context / __toString() and updates expectations accordingly.
tests/DispatchEngineTest.php Removes test for the deleted $onContextReady callback behavior.
tests/DispatchContextTest.php Adapts tests to configureRoute() and updated params handling.
src/Routines/UserAgent.php Switches request mutation to DispatchContext::withRequest().
src/Routines/FileExtension.php Moves negotiation storage from SplObjectStorage to request attributes.
src/Routines/ContentType.php Switches request mutation to DispatchContext::withRequest().
src/Routines/AbstractCallbackMediator.php Reworks negotiated callback storage to request attributes (but introduces shared mutable decline state).
src/Routes/AbstractRoute.php Uses withRequest() when writing request attributes during match.
src/Router.php Removes per-request state and injects pipeline/handlers/basePath when creating contexts.
src/DispatchEngine.php Stateless context creation; exposes pipeline getter; removes basePath mutation and callback coupling.
src/DispatchContext.php Implements externally immutable properties, constructor injection, basePath handling, and handler state reset logic.

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

DispatchContext:
- Constructor injection for RoutinePipeline, handlers, and basePath
  (removes setRoutinePipeline, setHandlers, setPath)
- All public properties use private(set), readable externally,
  writable only through internal methods (configureRoute, withRequest)
- Eliminate transient route mutations in matchRoute/routineMatch
- Move SplObjectStorage negotiation to request attributes
- Add handler state reset and error/exception isolation tests

DispatchEngine:
- Remove $onContextReady closure, no callback coupling
- Pure stateless dispatcher: creates fully-initialized contexts
- Expose routinePipeline() getter for Router::createDispatchContext

Router:
- Remove public $context property and __toString()
- No per-request state, immutable after route registration
@alganet alganet marked this pull request as ready for review March 25, 2026 14:32
@alganet alganet merged commit 64e698e into Respect:master Mar 25, 2026
3 checks passed
@alganet alganet deleted the fluent-2 branch March 25, 2026 14:45
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