Skip to content

Commit 44d7b51

Browse files
authored
Add interfaces for Context and ContextKey (#820)
* Add `ContextKeyInterface` * Add `ContextInterface` * Combine `SpanBuilderInterface::setParent()` and `::setNoParent()` * Remove `NullPropagator` * Fix `Context::with()` typehint * Remove `Context::withContextValue()` suggestion
1 parent 00c4299 commit 44d7b51

16 files changed

+110
-62
lines changed

Context.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,31 @@
44

55
namespace OpenTelemetry\Context;
66

7+
use function assert;
78
use function spl_object_id;
89

910
/**
1011
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/README.md#context
1112
*/
12-
final class Context
13+
final class Context implements ContextInterface
1314
{
1415
/** @var ContextStorageInterface&ExecutionContextAwareInterface */
1516
private static ContextStorageInterface $storage;
1617

1718
// Optimization for spans to avoid copying the context array.
18-
private static ContextKey $spanContextKey;
19+
private static ContextKeyInterface $spanContextKey;
1920
private ?object $span = null;
2021
/** @var array<int, mixed> */
2122
private array $context = [];
22-
/** @var array<int, ContextKey> */
23+
/** @var array<int, ContextKeyInterface> */
2324
private array $contextKeys = [];
2425

2526
private function __construct()
2627
{
2728
self::$spanContextKey = ContextKeys::span();
2829
}
2930

30-
public static function createKey(string $key): ContextKey
31+
public static function createKey(string $key): ContextKeyInterface
3132
{
3233
return new ContextKey($key);
3334
}
@@ -51,17 +52,29 @@ public static function storage(): ContextStorageInterface
5152
return self::$storage ??= new ContextStorage();
5253
}
5354

55+
/**
56+
* @param ContextInterface|false|null $context
57+
*
58+
* @internal
59+
*/
60+
public static function resolve($context, ?ContextStorageInterface $contextStorage = null): ContextInterface
61+
{
62+
return $context
63+
?? ($contextStorage ?? self::storage())->current()
64+
?: self::getRoot();
65+
}
66+
5467
/**
5568
* @internal
5669
*/
57-
public static function getRoot(): Context
70+
public static function getRoot(): ContextInterface
5871
{
5972
static $empty;
6073

6174
return $empty ??= new self();
6275
}
6376

64-
public static function getCurrent(): Context
77+
public static function getCurrent(): ContextInterface
6578
{
6679
return self::storage()->current();
6780
}
@@ -75,12 +88,12 @@ public function activate(): ScopeInterface
7588
return $scope;
7689
}
7790

78-
public function withContextValue(ImplicitContextKeyedInterface $value): Context
91+
public function withContextValue(ImplicitContextKeyedInterface $value): ContextInterface
7992
{
8093
return $value->storeInContext($this);
8194
}
8295

83-
public function with(ContextKey $key, $value): self
96+
public function with(ContextKeyInterface $key, $value): self
8497
{
8598
if ($this->get($key) === $value) {
8699
return $this;
@@ -108,9 +121,10 @@ public function with(ContextKey $key, $value): self
108121
return $self;
109122
}
110123

111-
public function get(ContextKey $key)
124+
public function get(ContextKeyInterface $key)
112125
{
113126
if ($key === self::$spanContextKey) {
127+
/** @psalm-suppress InvalidReturnStatement */
114128
return $this->span;
115129
}
116130

ContextInterface.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenTelemetry\Context;
6+
7+
interface ContextInterface
8+
{
9+
/**
10+
* @param non-empty-string $key
11+
*
12+
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/context.md#create-a-key
13+
*/
14+
public static function createKey(string $key): ContextKeyInterface;
15+
16+
public static function getCurrent(): ContextInterface;
17+
18+
/**
19+
* Makes `$this` the currently active {@see ContextInterface}.
20+
*/
21+
public function activate(): ScopeInterface;
22+
23+
/**
24+
* This adds a key/value pair to this Context.
25+
*
26+
* @psalm-template T
27+
* @psalm-param ContextKeyInterface<T> $key
28+
* @psalm-param T|null $value
29+
*/
30+
public function with(ContextKeyInterface $key, $value): ContextInterface;
31+
32+
public function withContextValue(ImplicitContextKeyedInterface $value): ContextInterface;
33+
34+
/**
35+
* Fetch a value from the Context given a key value.
36+
*
37+
* @psalm-template T
38+
* @psalm-param ContextKeyInterface<T> $key
39+
* @psalm-return T|null
40+
*/
41+
public function get(ContextKeyInterface $key);
42+
}

ContextKey.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace OpenTelemetry\Context;
66

7-
final class ContextKey
7+
/**
8+
* @internal
9+
*/
10+
final class ContextKey implements ContextKeyInterface
811
{
912
private ?string $name;
1013

ContextKeyInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenTelemetry\Context;
6+
7+
/**
8+
* @template-covariant T
9+
*/
10+
interface ContextKeyInterface
11+
{
12+
}

ContextKeys.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
*/
1010
final class ContextKeys
1111
{
12-
public static function span(): ContextKey
12+
public static function span(): ContextKeyInterface
1313
{
1414
static $instance;
1515

1616
return $instance ??= Context::createKey('opentelemetry-trace-span-key');
1717
}
1818

19-
public static function baggage(): ContextKey
19+
public static function baggage(): ContextKeyInterface
2020
{
2121
static $instance;
2222

ContextStorage.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ public function scope(): ?ContextStorageScopeInterface
4141
: null;
4242
}
4343

44-
public function current(): Context
44+
public function current(): ContextInterface
4545
{
4646
return $this->current->node->context ?? Context::getRoot();
4747
}
4848

49-
public function attach(Context $context): ContextStorageScopeInterface
49+
public function attach(ContextInterface $context): ContextStorageScopeInterface
5050
{
5151
return $this->current->node = new ContextStorageNode($context, $this->current, $this->current->node);
5252
}

ContextStorageInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface ContextStorageInterface
88
{
99
public function scope(): ?ContextStorageScopeInterface;
1010

11-
public function current(): Context;
11+
public function current(): ContextInterface;
1212

13-
public function attach(Context $context): ContextStorageScopeInterface;
13+
public function attach(ContextInterface $context): ContextStorageScopeInterface;
1414
}

ContextStorageNode.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
*/
1212
final class ContextStorageNode implements ScopeInterface, ContextStorageScopeInterface
1313
{
14-
public Context $context;
14+
public ContextInterface $context;
1515
public ContextStorageHead $head;
1616
private ?ContextStorageNode $previous;
1717
private array $localStorage = [];
1818

1919
public function __construct(
20-
Context $context,
20+
ContextInterface $context,
2121
ContextStorageHead $head,
2222
?ContextStorageNode $previous = null
2323
) {
@@ -50,7 +50,7 @@ public function offsetUnset($offset): void
5050
unset($this->localStorage[$offset]);
5151
}
5252

53-
public function context(): Context
53+
public function context(): ContextInterface
5454
{
5555
return $this->context;
5656
}

ContextStorageScopeInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
interface ContextStorageScopeInterface extends ScopeInterface, ArrayAccess
1010
{
11-
public function context(): Context;
11+
public function context(): ContextInterface;
1212

1313
/**
1414
* @param string $offset

FiberBoundContextStorage.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ public function scope(): ?ContextStorageScopeInterface
5757
return new FiberBoundContextStorageScope($scope);
5858
}
5959

60-
public function current(): Context
60+
public function current(): ContextInterface
6161
{
6262
$this->checkFiberMismatch();
6363

6464
return $this->storage->current();
6565
}
6666

67-
public function attach(Context $context): ContextStorageScopeInterface
67+
public function attach(ContextInterface $context): ContextStorageScopeInterface
6868
{
6969
$scope = $this->storage->attach($context);
7070
assert(class_exists(Fiber::class, false));

0 commit comments

Comments
 (0)