Skip to content

Commit c1b72de

Browse files
authored
Refactor Context (#746)
1 parent 7ca29ce commit c1b72de

File tree

1 file changed

+68
-77
lines changed

1 file changed

+68
-77
lines changed

Context.php

Lines changed: 68 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -9,55 +9,35 @@
99
*/
1010
final class Context
1111
{
12-
1312
/**
1413
* @var ContextStorageInterface&ExecutionContextAwareInterface
1514
*/
1615
private static ContextStorageInterface $storage;
17-
18-
private static ?Context $root = null;
19-
20-
/**
21-
* @internal
22-
*
23-
* @param ContextStorageInterface&ExecutionContextAwareInterface $storage
24-
*/
25-
public static function setStorage(ContextStorageInterface $storage): void
26-
{
27-
self::$storage = $storage;
28-
}
29-
16+
private static ?self $root = null;
17+
private ?ContextKey $key;
3018
/**
31-
* @return ContextStorageInterface&ExecutionContextAwareInterface
19+
* @var mixed
3220
*/
33-
public static function storage(): ContextStorageInterface
34-
{
35-
/** @psalm-suppress RedundantPropertyInitializationCheck */
36-
return self::$storage ??= new ContextStorage();
37-
}
21+
private $value;
22+
private ?self $parent;
3823

3924
/**
40-
* @param non-empty-string $key
25+
* This is a general purpose read-only key-value store. Read-only in the sense that adding a new value does not
26+
* mutate the existing context, but returns a new Context which has the new value added.
4127
*
42-
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/context.md#create-a-key
28+
* In practical terms, this is implemented as a linked list of Context instances, with each one holding a reference
29+
* to the key object, the value that corresponds to the key, and an optional reference to the parent Context
30+
* (i.e. the next link in the linked list chain)
31+
*
32+
* @param ContextKey|null $key The key object. Should only be null when creating an "empty" context
33+
* @param mixed $value
34+
* @param Context|null $parent Reference to the parent object
4335
*/
44-
public static function createKey(string $key): ContextKey
45-
{
46-
return new ContextKey($key);
47-
}
48-
49-
public static function getCurrent(): Context
50-
{
51-
return self::storage()->current();
52-
}
53-
54-
public static function getRoot(): self
36+
private function __construct(?ContextKey $key=null, $value=null, ?self $parent=null)
5537
{
56-
if (null === self::$root) {
57-
self::$root = new self();
58-
}
59-
60-
return self::$root;
38+
$this->key = $key;
39+
$this->value = $value;
40+
$this->parent = $parent;
6141
}
6242

6343
/**
@@ -66,69 +46,41 @@ public static function getRoot(): self
6646
* This will operate on the "current" global context in that scenario.
6747
*
6848
* There are two ways to call this function:
69-
* 1) With a $ctx value:
70-
* Context::getValue($key, $ctx) is functionally equivalent to $ctx->get($key)
71-
* 2) Without a $ctx value:
49+
* 1) With a $context value:
50+
* Context::getValue($key, $context) is functionally equivalent to $context->get($key)
51+
* 2) Without a $context value:
7252
* This will fetch the "current" Context if one exists or create one if not, then attempt to get the value from it.
7353
*
7454
* @param ContextKey $key
75-
* @param Context|null $ctx
55+
* @param Context|null $context
7656
*
7757
* @return mixed
7858
*/
79-
public static function getValue(ContextKey $key, ?Context $ctx=null)
59+
public static function getValue(ContextKey $key, ?self $context=null)
8060
{
81-
$ctx ??= self::getCurrent();
61+
$context ??= self::getCurrent();
8262

83-
return $ctx->get($key);
63+
return $context->get($key);
8464
}
8565

86-
private ?ContextKey $key;
87-
88-
/**
89-
* @var mixed
90-
*/
91-
private $value;
92-
93-
private ?Context $parent;
94-
9566
/**
96-
* This is a general purpose read-only key-value store. Read-only in the sense that adding a new value does not
97-
* mutate the existing context, but returns a new Context which has the new value added.
98-
*
99-
* In practical terms, this is implemented as a linked list of Context instances, with each one holding a reference
100-
* to the key object, the value that corresponds to the key, and an optional reference to the parent Context
101-
* (i.e. the next link in the linked list chain)
102-
*
103-
* @param ContextKey|null $key The key object. Should only be null when creating an "empty" context
104-
* @param mixed $value
105-
* @param Context|null $parent Reference to the parent object
106-
*/
107-
private function __construct(?ContextKey $key=null, $value=null, ?Context $parent=null)
108-
{
109-
$this->key = $key;
110-
$this->value = $value;
111-
$this->parent = $parent;
112-
}
113-
114-
/**
115-
* This adds a k/v pair to this Context. We do this by instantiating a new Context instance with the k/v and pass
67+
* This adds a key/value pair to this Context. We do this by instantiating a new Context instance with the key/value and pass
11668
* a reference to $this as the "parent" creating the linked list chain.
11769
*
11870
* @param ContextKey $key
11971
* @param mixed $value
12072
*
121-
* @return Context a new Context containing the k/v
73+
* @return Context a new Context containing the key/value
12274
*/
123-
public function with(ContextKey $key, $value): Context
75+
public function with(ContextKey $key, $value): self
12476
{
12577
return new self($key, $value, $this);
12678
}
12779

12880
/**
12981
* @todo: Implement this on the API side
13082
*/
131-
public function withContextValue(ImplicitContextKeyedInterface $value): Context
83+
public function withContextValue(ImplicitContextKeyedInterface $value): self
13284
{
13385
return $value->storeInContext($this);
13486
}
@@ -158,4 +110,43 @@ public function get(ContextKey $key)
158110

159111
return null;
160112
}
113+
114+
/**
115+
* @internal
116+
*
117+
* @param ContextStorageInterface&ExecutionContextAwareInterface $storage
118+
*/
119+
public static function setStorage(ContextStorageInterface $storage): void
120+
{
121+
self::$storage = $storage;
122+
}
123+
124+
/**
125+
* @return ContextStorageInterface&ExecutionContextAwareInterface
126+
*/
127+
public static function storage(): ContextStorageInterface
128+
{
129+
/** @psalm-suppress RedundantPropertyInitializationCheck */
130+
return self::$storage ??= new ContextStorage();
131+
}
132+
133+
/**
134+
* @param non-empty-string $key
135+
*
136+
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/context.md#create-a-key
137+
*/
138+
public static function createKey(string $key): ContextKey
139+
{
140+
return new ContextKey($key);
141+
}
142+
143+
public static function getCurrent(): self
144+
{
145+
return self::storage()->current();
146+
}
147+
148+
public static function getRoot(): self
149+
{
150+
return self::$root ??= new self();
151+
}
161152
}

0 commit comments

Comments
 (0)