|
1 | 1 | <?php |
2 | 2 |
|
3 | | -/** @noinspection PhpUndefinedClassInspection */ |
4 | | -/** @noinspection PhpUndefinedNamespaceInspection */ |
5 | | -/** @phan-file-suppress PhanUndeclaredClassReference */ |
| 3 | +/** @noinspection PhpUndefinedMethodInspection */ |
6 | 4 | /** @phan-file-suppress PhanUndeclaredClassCatch */ |
7 | 5 | /** @phan-file-suppress PhanUndeclaredClassMethod */ |
8 | 6 | /** @phan-file-suppress PhanUndeclaredMethod */ |
|
11 | 9 |
|
12 | 10 | namespace OpenTelemetry\Context; |
13 | 11 |
|
| 12 | +use function extension_loaded; |
14 | 13 | use FFI; |
15 | | -use FFI\Exception; |
| 14 | +use const FILTER_VALIDATE_BOOLEAN; |
| 15 | +use function filter_var; |
| 16 | +use function is_string; |
| 17 | +use const PHP_VERSION_ID; |
| 18 | +use function sprintf; |
| 19 | +use function trigger_error; |
16 | 20 |
|
17 | | -class ZendObserverFiber |
| 21 | +/** |
| 22 | + * @internal |
| 23 | + */ |
| 24 | +final class ZendObserverFiber |
18 | 25 | { |
19 | | - protected static $fibers = null; |
20 | | - |
21 | | - public function isEnabled(): bool |
| 26 | + public static function isEnabled(): bool |
22 | 27 | { |
23 | | - return ( |
24 | | - PHP_VERSION_ID >= 80100 && |
25 | | - (in_array(getenv('OTEL_PHP_FIBERS_ENABLED'), ['true', 'on', '1'])) && |
26 | | - class_exists(FFI::class) |
27 | | - ); |
| 28 | + $enabled = $_SERVER['OTEL_PHP_FIBERS_ENABLED'] ?? false; |
| 29 | + |
| 30 | + return is_string($enabled) |
| 31 | + ? filter_var($enabled, FILTER_VALIDATE_BOOLEAN) |
| 32 | + : (bool) $enabled; |
28 | 33 | } |
29 | 34 |
|
30 | | - /** |
31 | | - * @psalm-suppress UndefinedClass |
32 | | - */ |
33 | | - public function init(): bool |
| 35 | + public static function init(): bool |
34 | 36 | { |
35 | | - if (null === self::$fibers) { |
| 37 | + static $fibers; |
| 38 | + if ($fibers) { |
| 39 | + return true; |
| 40 | + } |
| 41 | + |
| 42 | + if (PHP_VERSION_ID < 80100 || !extension_loaded('ffi')) { |
| 43 | + trigger_error('Context: Fiber context switching not supported, requires PHP >= 8.1 and the FFI extension'); |
| 44 | + |
| 45 | + return false; |
| 46 | + } |
| 47 | + |
| 48 | + try { |
| 49 | + $fibers = FFI::scope('OTEL_ZEND_OBSERVER_FIBER'); |
| 50 | + } catch (FFI\Exception $e) { |
36 | 51 | try { |
37 | | - $fibers = FFI::scope('OTEL_ZEND_OBSERVER_FIBER'); |
38 | | - } catch (Exception $e) { |
39 | | - try { |
40 | | - $fibers = FFI::load(__DIR__ . '/fiber/zend_observer_fiber.h'); |
41 | | - } catch (Exception $e) { |
42 | | - return false; |
43 | | - } |
| 52 | + $fibers = FFI::load(__DIR__ . '/fiber/zend_observer_fiber.h'); |
| 53 | + } catch (FFI\Exception $e) { |
| 54 | + trigger_error(sprintf('Context: Fiber context switching not supported, %s', $e->getMessage())); |
| 55 | + |
| 56 | + return false; |
44 | 57 | } |
45 | | - $fibers->zend_observer_fiber_init_register(fn (int $initializing) => Context::storage()->fork($initializing)); //@phpstan-ignore-line |
46 | | - $fibers->zend_observer_fiber_switch_register(fn (int $from, int $to) => Context::storage()->switch($to)); //@phpstan-ignore-line |
47 | | - $fibers->zend_observer_fiber_destroy_register(fn (int $destroying) => Context::storage()->destroy($destroying)); //@phpstan-ignore-line |
48 | | - self::$fibers = $fibers; |
49 | 58 | } |
50 | 59 |
|
| 60 | + $fibers->zend_observer_fiber_init_register(static fn (int $initializing) => Context::storage()->fork($initializing)); //@phpstan-ignore-line |
| 61 | + $fibers->zend_observer_fiber_switch_register(static fn (int $from, int $to) => Context::storage()->switch($to)); //@phpstan-ignore-line |
| 62 | + $fibers->zend_observer_fiber_destroy_register(static fn (int $destroying) => Context::storage()->destroy($destroying)); //@phpstan-ignore-line |
| 63 | + |
51 | 64 | return true; |
52 | 65 | } |
53 | 66 | } |
0 commit comments