|
14 | 14 | use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler; |
15 | 15 | use OpenTelemetry\SDK\Trace\Sampler\ParentBased; |
16 | 16 | use function register_shutdown_function; |
| 17 | +use function spl_object_id; |
| 18 | +use WeakReference; |
17 | 19 |
|
18 | 20 | final class TracerProvider implements API\TracerProviderInterface |
19 | 21 | { |
20 | 22 | public const DEFAULT_TRACER_NAME = 'io.opentelemetry.contrib.php'; |
21 | 23 |
|
| 24 | + /** @var array<int, WeakReference<self>>|null */ |
| 25 | + private static ?array $tracerProviders = null; |
22 | 26 | private static ?API\TracerInterface $defaultTracer = null; |
23 | 27 |
|
24 | 28 | /** @var array<string, API\TracerInterface> */ |
@@ -53,7 +57,7 @@ public function __construct( |
53 | 57 | $spanProcessors |
54 | 58 | ); |
55 | 59 |
|
56 | | - register_shutdown_function([$this, 'shutdown']); |
| 60 | + self::registerShutdownFunction($this); |
57 | 61 | } |
58 | 62 |
|
59 | 63 | public function forceFlush(): ?bool |
@@ -116,6 +120,41 @@ public function shutdown(): bool |
116 | 120 | return true; |
117 | 121 | } |
118 | 122 |
|
| 123 | + self::unregisterShutdownFunction($this); |
| 124 | + |
119 | 125 | return $this->tracerSharedState->shutdown(); |
120 | 126 | } |
| 127 | + |
| 128 | + public function __destruct() |
| 129 | + { |
| 130 | + $this->shutdown(); |
| 131 | + } |
| 132 | + |
| 133 | + private static function registerShutdownFunction(TracerProvider $tracerProvider): void |
| 134 | + { |
| 135 | + if (self::$tracerProviders === null) { |
| 136 | + register_shutdown_function(static function (): void { |
| 137 | + $tracerProviders = self::$tracerProviders; |
| 138 | + self::$tracerProviders = null; |
| 139 | + |
| 140 | + // Push tracer provider shutdown to end of queue |
| 141 | + // @phan-suppress-next-line PhanTypeMismatchArgumentInternal |
| 142 | + register_shutdown_function(static function (array $tracerProviders): void { |
| 143 | + foreach ($tracerProviders as $reference) { |
| 144 | + if ($tracerProvider = $reference->get()) { |
| 145 | + $tracerProvider->shutdown(); |
| 146 | + } |
| 147 | + } |
| 148 | + }, $tracerProviders); |
| 149 | + }); |
| 150 | + } |
| 151 | + |
| 152 | + self::$tracerProviders[spl_object_id($tracerProvider)] = WeakReference::create($tracerProvider); |
| 153 | + } |
| 154 | + |
| 155 | + private static function unregisterShutdownFunction(TracerProvider $tracerProvider): void |
| 156 | + { |
| 157 | + /** @psalm-suppress PossiblyNullArrayAccess */ |
| 158 | + unset(self::$tracerProviders[spl_object_id($tracerProvider)]); |
| 159 | + } |
121 | 160 | } |
0 commit comments