0
# Context Management
1
2
Core context creation, attachment, and value propagation functionality for maintaining scoped state across API boundaries and thread switches.
3
4
## Capabilities
5
6
### Root Context
7
8
The logical root context which is the ultimate ancestor of all contexts. This context is not cancellable and will not cascade cancellation or retain listeners.
9
10
```java { .api }
11
/**
12
* The logical root context which is the ultimate ancestor of all contexts.
13
* Never assume this is the default context for new threads.
14
*/
15
public static final Context ROOT;
16
```
17
18
### Current Context Access
19
20
Returns the context associated with the current scope, never returns null. Will never return CancellableContext even if one is attached.
21
22
```java { .api }
23
/**
24
* Return the context associated with the current scope, will never return null.
25
* @return The current context, or ROOT if no context is attached
26
*/
27
public static Context current();
28
```
29
30
### Context Key Creation
31
32
Create typed keys for storing and retrieving values from contexts. Keys use reference equality and provide type safety.
33
34
```java { .api }
35
/**
36
* Create a Key with the given debug name.
37
* @param debugString Name for debugging purposes, does not impact behavior
38
* @return New Key instance for the specified type
39
*/
40
public static <T> Context.Key<T> key(String debugString);
41
42
/**
43
* Create a Key with the given debug name and default value.
44
* @param debugString Name for debugging purposes
45
* @param defaultValue Default value returned when key is not found
46
* @return New Key instance with default value
47
*/
48
public static <T> Context.Key<T> keyWithDefault(String debugString, T defaultValue);
49
```
50
51
**Usage Examples:**
52
53
```java
54
// Create keys for different types of context data
55
Context.Key<String> USER_ID_KEY = Context.key("userId");
56
Context.Key<String> REQUEST_ID_KEY = Context.key("requestId");
57
Context.Key<Integer> TIMEOUT_KEY = Context.keyWithDefault("timeout", 30);
58
59
// Keys are compared by reference equality
60
Context.Key<String> anotherUserKey = Context.key("userId"); // Different key!
61
assert USER_ID_KEY != anotherUserKey;
62
```
63
64
### Context Value Setting
65
66
Create new contexts with additional key-value pairs. Context objects are immutable, so setting values creates new context instances.
67
68
```java { .api }
69
/**
70
* Create a new context with the given key value set.
71
* @param key The key to set
72
* @param value The value to associate with the key
73
* @return New context instance with the key-value pair
74
*/
75
public <V> Context withValue(Context.Key<V> key, V value);
76
77
/**
78
* Create a new context with two key-value pairs.
79
*/
80
public <V1, V2> Context withValues(Context.Key<V1> k1, V1 v1, Context.Key<V2> k2, V2 v2);
81
82
/**
83
* Create a new context with three key-value pairs.
84
*/
85
public <V1, V2, V3> Context withValues(Context.Key<V1> k1, V1 v1, Context.Key<V2> k2, V2 v2, Context.Key<V3> k3, V3 v3);
86
87
/**
88
* Create a new context with four key-value pairs.
89
*/
90
public <V1, V2, V3, V4> Context withValues(Context.Key<V1> k1, V1 v1, Context.Key<V2> k2, V2 v2, Context.Key<V3> k3, V3 v3, Context.Key<V4> k4, V4 v4);
91
```
92
93
**Usage Examples:**
94
95
```java
96
Context.Key<String> USER_KEY = Context.key("user");
97
Context.Key<String> ROLE_KEY = Context.key("role");
98
99
// Single value
100
Context withUser = Context.current().withValue(USER_KEY, "alice");
101
102
// Multiple values - these are equivalent:
103
Context withUserAndRole1 = Context.current().withValues(USER_KEY, "alice", ROLE_KEY, "admin");
104
Context withUserAndRole2 = Context.current()
105
.withValue(USER_KEY, "alice")
106
.withValue(ROLE_KEY, "admin");
107
```
108
109
### Context Forking
110
111
Create a new context which propagates the values of the current context but does not cascade its cancellation.
112
113
```java { .api }
114
/**
115
* Create a new context which propagates values but does not cascade cancellation.
116
* @return New context that inherits values but not cancellation status
117
*/
118
public Context fork();
119
```
120
121
**Usage Example:**
122
123
```java
124
Context.Key<String> DATA_KEY = Context.key("data");
125
Context withData = Context.current().withValue(DATA_KEY, "important");
126
127
// Create a forked context that won't be cancelled when parent is cancelled
128
Context forkedContext = withData.fork();
129
forkedContext.run(() -> {
130
// This code will continue running even if the parent context is cancelled
131
String data = DATA_KEY.get(); // "important"
132
performIndependentTask(data);
133
});
134
```
135
136
### Context Attachment and Detachment
137
138
Attach and detach contexts to control the current scope. Every attach() should have a corresponding detach() in the same method.
139
140
```java { .api }
141
/**
142
* Attach this context, entering a new scope within which this context is current.
143
* @return The previously current context that should be passed to detach()
144
*/
145
public Context attach();
146
147
/**
148
* Reverse an attach(), restoring the previous context and exiting the current scope.
149
* @param toAttach The context that was returned by the corresponding attach() call
150
*/
151
public void detach(Context toAttach);
152
```
153
154
**Usage Example:**
155
156
```java
157
Context.Key<String> USER_KEY = Context.key("user");
158
Context withUser = Context.current().withValue(USER_KEY, "alice");
159
160
// Proper attach/detach pattern
161
Context previous = withUser.attach();
162
try {
163
// Code here runs with withUser as the current context
164
String user = USER_KEY.get(); // "alice"
165
processUserRequest(user);
166
} finally {
167
withUser.detach(previous);
168
}
169
```
170
171
### Key Value Retrieval
172
173
Retrieve values from contexts using keys. Keys provide type-safe access to stored values.
174
175
```java { .api }
176
public static final class Key<T> {
177
/**
178
* Get the value from the current context for this key.
179
* @return The value associated with this key, or the default value if not found
180
*/
181
public T get();
182
183
/**
184
* Get the value from the specified context for this key.
185
* @param context The context to retrieve the value from
186
* @return The value associated with this key, or the default value if not found
187
*/
188
public T get(Context context);
189
190
/**
191
* String representation of this key (returns the debug name).
192
* @return The debug name provided when the key was created
193
*/
194
public String toString();
195
}
196
```
197
198
**Usage Example:**
199
200
```java
201
Context.Key<String> USER_KEY = Context.key("user");
202
Context.Key<Integer> TIMEOUT_KEY = Context.keyWithDefault("timeout", 30);
203
204
Context withValues = Context.current()
205
.withValue(USER_KEY, "alice")
206
.withValue(TIMEOUT_KEY, 60);
207
208
withValues.run(() -> {
209
String user = USER_KEY.get(); // "alice"
210
Integer timeout = TIMEOUT_KEY.get(); // 60
211
212
// Can also get from specific context
213
String userFromContext = USER_KEY.get(withValues); // "alice"
214
});
215
```