> Fiber-specific scope stacks */ private array $stack = []; #[Initializer] public static function initialize(): self { return new self(); } /** * Enter a new error scope * * @param ErrorScopeContext $context Scope context to enter * @return int Token for leaving this scope (stack depth) */ public function enter(ErrorScopeContext $context): int { $id = $this->fiberId(); $this->stack[$id] ??= []; $this->stack[$id][] = $context; return count($this->stack[$id]); } /** * Exit error scope(s) * * @param int $token Token from enter() - exits all scopes until this depth */ public function exit(int $token = 0): void { $id = $this->fiberId(); if (!isset($this->stack[$id])) { return; } if ($token === 0) { // Exit only the most recent scope array_pop($this->stack[$id]); } else { // Exit all scopes until token depth while (!empty($this->stack[$id]) && count($this->stack[$id]) >= $token) { array_pop($this->stack[$id]); } } // Cleanup empty stack if (empty($this->stack[$id])) { unset($this->stack[$id]); } } /** * Get current error scope context * * @return ErrorScopeContext|null Current scope or null if no scope active */ public function current(): ?ErrorScopeContext { $id = $this->fiberId(); $stack = $this->stack[$id] ?? []; $current = end($stack); return $current !== false ? $current : null; } /** * Check if any scope is active */ public function hasScope(): bool { $id = $this->fiberId(); return !empty($this->stack[$id]); } /** * Get scope depth (number of nested scopes) */ public function depth(): int { $id = $this->fiberId(); return count($this->stack[$id] ?? []); } /** * Get fiber ID for isolation * * Returns 0 for main fiber, unique ID for each Fiber */ private function fiberId(): int { $fiber = Fiber::getCurrent(); return $fiber ? spl_object_id($fiber) : 0; } /** * Clear all scopes (for testing/cleanup) */ public function clear(): void { $this->stack = []; } /** * Get statistics for monitoring */ public function getStats(): array { return [ 'active_fibers' => count($this->stack), 'total_scopes' => array_sum(array_map('count', $this->stack)), 'max_depth' => !empty($this->stack) ? max(array_map('count', $this->stack)) : 0, ]; } }