Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions src/Phaseolies/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Phaseolies\DI\Container;
use Phaseolies\Config\Config;
use Phaseolies\Support\DeferScope;
use Phaseolies\Support\ExecutionContext;
use Phaseolies\ApplicationBuilder;
use Devium\Toml\Toml;
use RuntimeException;
Expand Down Expand Up @@ -1138,8 +1139,13 @@ public function terminate(
Request $request,
?Response $response = null,
?\Throwable $exception = null,
?DeferScope $deferScope = null
?DeferScope $deferScope = null,
?ExecutionContext $context = null
): void {
if ($context !== null) {
$this->resumeContext($context);
}

if ($deferScope !== null) {
// Make the request scope current again so terminating callbacks
// can still defer cleanup into it.
Expand All @@ -1164,7 +1170,13 @@ public function terminate(
$this->endDeferScope($deferScope, $terminationFailure ?? $exception);
}
} finally {
$this->cleanupRequestScopedServices();
try {
$this->cleanupRequestScopedServices();
} finally {
if ($context !== null) {
$this->endContext($context);
}
}
}
}
}
Expand Down Expand Up @@ -1512,6 +1524,7 @@ public function dispatch($request): DispatchResult
{
$this->snapshotBootBindings();

$context = $this->beginContext(ExecutionContext::REQUEST, $this->requestContextMetadata($request));
$deferScope = $this->beginDeferScope();

try {
Expand All @@ -1522,24 +1535,51 @@ public function dispatch($request): DispatchResult
$response->prepare($request)->send();

$this->suspendDeferScope($deferScope);
$this->suspendContext($context);

return new DispatchResult($this, $request, $response, null, $deferScope);
return new DispatchResult($this, $request, $response, null, $deferScope, $context);
} catch (HttpException $e) {
try {
Response::dispatchHttpException($e);
} catch (\Throwable $renderFailure) {
$this->endDeferScope($deferScope, $renderFailure);
$this->endContext($context);

throw $renderFailure;
}

$this->suspendDeferScope($deferScope);
$this->suspendContext($context);

return new DispatchResult($this, $request, null, $e, $deferScope);
return new DispatchResult($this, $request, null, $e, $deferScope, $context);
} catch (\Throwable $e) {
$this->endDeferScope($deferScope, $e);
$this->endContext($context);

throw $e;
}
}

/**
* Describe a request for its execution context. Must never throw.
*
* @param mixed $request
* @return array<string, mixed>
*/
protected function requestContextMetadata($request): array
{
$metadata = [];

try {
$metadata = array_filter([
'method' => $request->method(),
'path' => $request->getPath(),
'request_id' => $request->header('X-Request-Id'),
], static fn($value) => $value !== null && $value !== '');
} catch (\Throwable) {
// Metadata is best-effort; the request must still be served.
}

return $metadata;
}
}
6 changes: 5 additions & 1 deletion src/Phaseolies/Console/Console.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ protected function bootstrapCommands(): void
*/
protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output): int
{
return $this->app->runInDeferScope(fn() => parent::doRunCommand($command, $input, $output));
return $this->app->runInContext(
'console',
['command' => $command->getName()],
fn() => $this->app->runInDeferScope(fn() => parent::doRunCommand($command, $input, $output))
);
}
}
Loading
Loading