@@ -136,11 +136,7 @@ public function __construct(Adapter $server, string $timezone)
136136 date_default_timezone_set ($ timezone );
137137 $ this ->files = new Files ();
138138 $ this ->server = $ server ;
139- // Capture the global container at construction. INVARIANT: `Http`
140- // is constructed at boot, never inside a request. With no
141- // coroutine active, getContext() returns the global container
142- // directly — so this capture is stable for the lifetime of the
143- // Http instance.
139+ // Captures the global container; assumes Http is constructed at boot, not inside a request.
144140 $ this ->container = $ server ->getContext ();
145141 $ this ->setTelemetry (new NoTelemetry ());
146142 }
@@ -411,13 +407,8 @@ public function setResource(string $name, callable $callback, array $injections
411407 }
412408
413409 /**
414- * Set a request-scoped value on the current request's context container.
415- *
416- * The framework convention is: `setResource()` registers singletons on
417- * the global container; `setContext()` registers per-request values on
418- * the adapter's request container, which is coroutine-local under the
419- * Swoole adapters. `getResource()` reads from the request container
420- * with parent-fallback to the global one, so either kind resolves.
410+ * Register a per-request value on the context container.
411+ * Counterpart to setResource() for global singletons.
421412 *
422413 * @param list<string> $injections
423414 */
@@ -605,9 +596,7 @@ public function execute(Route $route, Request $request, Response $response): sta
605596 $ context = $ this ->server ->getContext ();
606597 $ match = $ context ->has ('match ' ) ? $ context ->get ('match ' ) : null ;
607598 if (!$ match instanceof RouteMatch || $ match ->route !== $ route ) {
608- // execute() called directly (e.g. from a test) without a prior
609- // match() — synthesize a RouteMatch so shutdown / error hooks
610- // injecting 'match' still see the route they're running under.
599+ // execute() called directly without a prior match().
611600 $ match = new RouteMatch ($ route , '' );
612601 $ context ->set ('match ' , fn () => $ match );
613602 }
@@ -636,11 +625,6 @@ public function execute(Route $route, Request $request, Response $response): sta
636625 if (!$ response ->isSent ()) {
637626 $ arguments = $ this ->getArguments ($ route , $ pathValues , $ request ->getParams ());
638627
639- // Update the per-request RouteMatch with the resolved+
640- // validated argument map so shutdown / error hooks can
641- // read the same values the action saw — e.g. for label
642- // substitution like {request.fileId}. Race-free because
643- // the context container is per-request.
644628 $ resolved = [];
645629 foreach ($ route ->getParams () as $ name => $ param ) {
646630 $ resolved [$ name ] = $ arguments [$ param ['order ' ]] ?? null ;
@@ -791,10 +775,6 @@ private function runInternal(Request $request, Response $response): static
791775
792776 $ this ->setContext ('request ' , fn () => $ request );
793777 $ this ->setContext ('response ' , fn () => $ response );
794- // Seed 'match' to null up front so requestHooks, the global error
795- // path, and any pre-routing code can read it without tripping the
796- // "Failed to find resource" error from getResource('match'). It
797- // gets overwritten with the real RouteMatch once match() runs.
798778 $ this ->setContext ('match ' , fn () => null );
799779
800780 try {
@@ -869,8 +849,7 @@ private function runInternal(Request $request, Response $response): static
869849 }
870850
871851 if (null === $ route && null !== self ::$ wildcardRoute ) {
872- // Clone so we can stamp the request URI onto $path without
873- // mutating the singleton shared across concurrent coroutines.
852+ // Clone before stamping $path so concurrent coroutines don't fight over the singleton.
874853 $ route = clone self ::$ wildcardRoute ;
875854 $ path = parse_url ($ request ->getURI (), PHP_URL_PATH );
876855 $ path = \is_string ($ path ) ? ($ path === '' ? '/ ' : $ path ) : '/ ' ;
0 commit comments