Skip to content

Commit 0707b7c

Browse files
loks0nclaude
andcommitted
Split Adapter::getContainer() into getContainer + getContext
Before, getContainer() did double duty: returning the request-scoped container when inside a coroutine, the global container otherwise. That made request-side reads/writes look like global ones (\$server->getContainer() inside match()), which obscured the scope split. Now: - getContainer() always returns the global singleton container. - getContext() returns the per-request context container (coroutine-local under Swoole, identical to the global one under FPM). Lookups still fall through to the global container's parent chain, so getContext() resolves singletons too. Http internals updated to call getContext() for all per-request reads and writes; the constructor's setup of \$this->container keeps using getContainer() since it's grabbing the global. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2da69df commit 0707b7c

5 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/Http/Adapter.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,21 @@ abstract class Adapter
1111
abstract public function onStart(callable $callback): void;
1212
abstract public function onRequest(callable $callback): void;
1313
abstract public function start(): void;
14+
15+
/**
16+
* Return the global container — the singleton-scoped registry shared
17+
* across all requests. Use this for resources that should outlive a
18+
* single request (clients, configs, etc.).
19+
*/
1420
abstract public function getContainer(): Container;
21+
22+
/**
23+
* Return the per-request context container. Coroutine-local under the
24+
* Swoole adapters; identical to getContainer() under FPM. Use this for
25+
* values scoped to a single request — request, response, route,
26+
* matchedPath, error, etc. Lookups fall through to the global
27+
* container's parent chain, so getContext()->get('someSingleton')
28+
* still resolves.
29+
*/
30+
abstract public function getContext(): Container;
1531
}

src/Http/Adapter/FPM/Server.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,10 @@ public function getContainer(): Container
3030
return $this->container;
3131
}
3232

33+
public function getContext(): Container
34+
{
35+
return $this->container;
36+
}
37+
3338
public function start(): void {}
3439
}

src/Http/Adapter/Swoole/Server.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public function onRequest(callable $callback): void
3939
}
4040

4141
public function getContainer(): Container
42+
{
43+
return $this->container;
44+
}
45+
46+
public function getContext(): Container
4247
{
4348
if (Coroutine::getCid() !== -1) {
4449
return Coroutine::getContext()[self::CONTEXT_KEY] ?? $this->container;

src/Http/Adapter/SwooleCoroutine/Server.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public function onRequest(callable $callback): void
5151
}
5252

5353
public function getContainer(): Container
54+
{
55+
return $this->container;
56+
}
57+
58+
public function getContext(): Container
5459
{
5560
return Coroutine::getContext()[self::CONTEXT_KEY] ?? $this->container;
5661
}

src/Http/Http.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public static function setAllowOverride(bool $value): void
363363
public function getResource(string $name): mixed
364364
{
365365
try {
366-
return $this->server->getContainer()->get($name);
366+
return $this->server->getContext()->get($name);
367367
} catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
368368
// Normalize DI container errors to the Http layer's "resource" terminology.
369369
$message = str_replace('dependency', 'resource', $e->getMessage());
@@ -418,7 +418,7 @@ public function setResource(string $name, callable $callback, array $injections
418418
*/
419419
protected function setContext(string $name, callable $callback, array $injections = []): void
420420
{
421-
$this->server->getContainer()->set($name, $callback, $injections);
421+
$this->server->getContext()->set($name, $callback, $injections);
422422
}
423423

424424
/**
@@ -569,7 +569,7 @@ public function start(): void
569569
*/
570570
public function match(Request $request, bool $fresh = true): ?Route
571571
{
572-
$context = $this->server->getContainer();
572+
$context = $this->server->getContext();
573573

574574
if (!$fresh && $context->has('route')) {
575575
$cached = $context->get('route');
@@ -605,7 +605,7 @@ public function execute(Route $route, Request $request, Response $response): sta
605605
$arguments = [];
606606
$groups = $route->getGroups();
607607

608-
$context = $this->server->getContainer();
608+
$context = $this->server->getContext();
609609
$matchedPath = $context->has('matchedPath') ? $context->get('matchedPath') : '';
610610
$preparedPath = Router::preparePath($matchedPath);
611611
$pathValues = $route->getPathValues($request, $preparedPath[0]);
@@ -738,7 +738,7 @@ public function run(Request $request, Response $response): static
738738
$result = $this->runInternal($request, $response);
739739

740740
$requestDuration = microtime(true) - $start;
741-
$context = $this->server->getContainer();
741+
$context = $this->server->getContext();
742742
$route = $context->has('route') ? $context->get('route') : null;
743743
$attributes = [
744744
'url.scheme' => $request->getProtocol(),

0 commit comments

Comments
 (0)