question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide a way to attach a resource when a RequestContext is pushed

See original GitHub issue

Let’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:open
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
trustincommented, Aug 3, 2021

Sure. Let’s close it for now, then. We can revisit this whenever we need it.

0reactions
ikhooncommented, Aug 4, 2021

I realized that the signature of RequestContextStorageListener is similar to AbstractCoroutineContextElement. https://github.com/line/armeria/blob/833077b818140669d5b6c051e1d0a544c5bdcf05/examples/annotated-http-service-kotlin/src/main/kotlin/example/armeria/server/annotated/kotlin/ArmeriaRequestContext.kt#L14-L24

Let me reopen this and have random discussions on this topic. 😆

Read more comments on GitHub >

github_iconTop Results From Across the Web

Provide more ways to run with Context · Issue #2611 - GitHub
In our codebase, we push RequestContext and immediately run some code with try-with-resources. For example: try (SafeCloseable ignored ...
Read more >
The Request Context — Flask Documentation (2.2.x)
When the request starts, a RequestContext is created and pushed, which creates and pushes an AppContext first if a context for that application...
Read more >
What is the purpose of Flask's context stacks? - Stack Overflow
All these are declared at application start-up, but do not actually resolve to anything until a request context or application context is pushed...
Read more >
Lambda event source mappings - AWS Documentation
An event source mapping is a Lambda resource that reads from an event source and ... provides event source mappings and how-to fine...
Read more >
Push Options - GitLab Docs
Provide CI/CD variables to be used in a CI pipeline, if one is created due to the push. 12.6. An example of using...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found