class DebugScope
@internal
Hierarchy
- class \OpenTelemetry\Context\DebugScope implements \OpenTelemetry\Context\ScopeInterface
Expanded class hierarchy of DebugScope
File
-
vendor/
open-telemetry/ context/ DebugScope.php, line 23
Namespace
OpenTelemetry\ContextView source
final class DebugScope implements ScopeInterface {
private static bool $shutdownHandlerInitialized = false;
private static bool $finalShutdownPhase = false;
private readonly ?int $fiberId;
private readonly array $createdAt;
private ?array $detachedAt = null;
public function __construct(ContextStorageScopeInterface $scope) {
$this->fiberId = self::currentFiberId();
$this->createdAt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
if (!self::$shutdownHandlerInitialized) {
self::$shutdownHandlerInitialized = true;
register_shutdown_function('register_shutdown_function', static fn() => self::$finalShutdownPhase = true);
}
}
public function detach() : int {
$this->detachedAt ??= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$flags = $this->scope
->detach();
if (($flags & ScopeInterface::DETACHED) !== 0) {
trigger_error(sprintf('Scope: unexpected call to Scope::detach() for scope #%d, scope was already detached %s', spl_object_id($this), self::formatBacktrace($this->detachedAt)));
}
elseif (($flags & ScopeInterface::MISMATCH) !== 0) {
trigger_error(sprintf('Scope: unexpected call to Scope::detach() for scope #%d, scope successfully detached but another scope should have been detached first', spl_object_id($this)));
}
elseif (($flags & ScopeInterface::INACTIVE) !== 0) {
trigger_error(sprintf('Scope: unexpected call to Scope::detach() for scope #%d, scope successfully detached from different execution context', spl_object_id($this)));
}
return $flags;
}
public function __destruct() {
if (!$this->detachedAt) {
// Handle destructors invoked during final shutdown
// DebugScope::__destruct() might be called before fiber finally blocks run
if (self::$finalShutdownPhase && $this->fiberId !== self::currentFiberId()) {
return;
}
trigger_error(sprintf('Scope: missing call to Scope::detach() for scope #%d, created %s', spl_object_id($this->scope), self::formatBacktrace($this->createdAt)));
}
}
/**
* @phan-suppress PhanUndeclaredClassReference
* @phan-suppress PhanUndeclaredClassMethod
*/
private static function currentFiberId() : ?int {
if (PHP_VERSION_ID < 80100) {
return null;
}
assert(class_exists(Fiber::class, false));
if (!($fiber = Fiber::getCurrent())) {
return null;
}
return spl_object_id($fiber);
}
private static function formatBacktrace(array $trace) : string {
$s = '';
for ($i = 0, $n = count($trace) + 1; ++$i < $n;) {
$s .= "\n\t";
$s .= 'at ';
if (isset($trace[$i]['class'])) {
$s .= strtr($trace[$i]['class'], [
'\\' => '.',
]);
$s .= '.';
}
$s .= strtr($trace[$i]['function'] ?? '{main}', [
'\\' => '.',
]);
$s .= '(';
if (isset($trace[$i - 1]['file'])) {
$s .= basename((string) $trace[$i - 1]['file']);
if (isset($trace[$i - 1]['line'])) {
$s .= ':';
$s .= $trace[$i - 1]['line'];
}
}
else {
$s .= 'Unknown Source';
}
$s .= ')';
}
return $s . "\n";
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
DebugScope::$createdAt | private | property | ||
DebugScope::$detachedAt | private | property | ||
DebugScope::$fiberId | private | property | ||
DebugScope::$finalShutdownPhase | private static | property | ||
DebugScope::$shutdownHandlerInitialized | private static | property | ||
DebugScope::currentFiberId | private static | function | @phan-suppress PhanUndeclaredClassReference @phan-suppress PhanUndeclaredClassMethod |
|
DebugScope::detach | public | function | Detaches the context associated with this scope and restores the previously associated context. |
Overrides ScopeInterface::detach |
DebugScope::formatBacktrace | private static | function | ||
DebugScope::__construct | public | function | ||
DebugScope::__destruct | public | function | ||
ScopeInterface::DETACHED | public | constant | The associated context was already detached. | |
ScopeInterface::INACTIVE | public | constant | The associated context is not in the active execution context. | |
ScopeInterface::MISMATCH | public | constant | The associated context is not the active context. |