Provide a way to attach a resource when a RequestContext is pushed
See original GitHub issueLet’s say there is a resource that wants to be created when a RequestContext is pushed and
the resource should be closed when the RequestContext is popped. Because the resource should
only exist when the request context is active. We can manage the lifecycle of the resource.
by implementing a custom RequestContextStorage.
static final ThreadLocal<Deque<AutoCloseable>> threadLocal = ThreadLocal.withInitial(() -> new ArrayDeque<>());
new RequestContextStorageWrapper(contextStorage) {
public <T extends RequestContext> T push(RequestContext toPush) {
final Scope scope = currentTraceContext.decorateScope(traceContext, CONTEXT_SCOPE);
threadLocal.get().push(scope);
return super.push(toPush);
}
public void pop(RequestContext current, @Nullable RequestContext toRestore) {
final ArrayDeque<Scope> stack = threadLocal.get();
if (!stack.isEmpty()) {
final Scope scope = stack.pop();
scope.close();
}
super.pop(current, toRestore);
}
}
In this case, we can not set the Scope to the attributes of RequestContext because
a RequestContext could be pushed to two different threads at the same time.
Suggestion
It would be nice to attach an arbitrary object when a RequestContext is pushed and
the attached object will be passed when the RequestContext is popped off.
interface Attachment {
void set(Object obj);
}
interface RequestContextStorage {
<T extends RequestContext> T push(RequestContext toPush, Attatchment attachment);
void pop(RequestContext current, @Nullable RequestContext toRestore, @Nullable Object attached);
}
If we change RequestContextStorage API with the suggested design, we can remove the ThreadLocal
and simplify the above example like the following:
new RequestContextStorageWrapper(contextStorage) {
public <T extends RequestContext> T push(RequestContext toPush, Attatchment attachment) {
final Scope scope = currentTraceContext.decorateScope(traceContext, CONTEXT_SCOPE);
attatchment.set(scope);
return super.push(toPush);
}
public void pop(RequestContext current, @Nullable RequestContext toRestore, @Nullable Object attached) {
assert attached instanceof Scope;
((Scope) attached).close();
super.pop(current, toRestore);
}
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (5 by maintainers)

Top Related StackOverflow Question
Sure. Let’s close it for now, then. We can revisit this whenever we need it.
I realized that the signature of
RequestContextStorageListeneris similar toAbstractCoroutineContextElement. https://github.com/line/armeria/blob/833077b818140669d5b6c051e1d0a544c5bdcf05/examples/annotated-http-service-kotlin/src/main/kotlin/example/armeria/server/annotated/kotlin/ArmeriaRequestContext.kt#L14-L24Let me reopen this and have random discussions on this topic. 😆