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.

RequestContextController spec impossible to implement

See original GitHub issue

I’m not really happy with the RequestContextController. And it appears to me that the spec is broken.

Here is the important part from the spec:

6.5.2. Activating Built In Contexts Certain built in contexts support the ability to be activated and deactivated. This allows developers to control built-in contexts in ways that they could also manage custom built contexts. When activating and deactivating built in contexts, it is important to realize that they can only be activated if not already active within a given thread. 6.5.2.1. Activating a Request Context Request contexts can be managed either programmatically or via interceptor. To programmatically manage request contexts, the container provides a built in bean that is @Dependent scoped and of type RequestContextController that allows you to activate and deactivate a request context on the current thread. The object should be considered stateful, invoking the same instance on different threads may not work properly, non-portable behavior may occur. public interface RequestContextController { boolean activate(); void deactivate() throws ContextNotActiveException; } When the activate() method is called, if the request context is not already active on the current thread then it will be activated and the method returns true. Otherwise, the method returns false. When the deactivate() method is called, if this controller started the request context then the request context is stopped. The method does nothing if this controller did not activate the context

The problem is that there are 2 ways to use that part

a.)

boolean didActivate = reqCtxCtrl.activate();
...
if (didActivate) reqCtxCrl.deactivate();

b.)

try {
  reqCtxCtrl.activate();
  ...
} finally {
  reqCtxCrl.deactivate();
}

The problematic part is nesting. In case a) we got maybe 7 calls to activate() but only 1 to deactivate. In case b) we got 7 calls to activate and 7 to deactivate();

There is simply no way to implement this in a clean way. A simple boolean flag does not help because of concurrency. A ThreadLocal<List> does not help much either. If we use a ThreadLocal<Boolean> we potentially leak memory in case of a). If we close immediately we potentially close way too early in case b).

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:20 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
Ladicekcommented, May 18, 2021

I mean – I believe that at this point, we conclusively established that RCC is possible to implement (contrary to this issue’s title). We also established that there are code patterns that make RCC usage safe.

We’re just debating problematic scenarios that stem from incorrect usage of RCC. That incorrectness stems from the nature of global state and has nothing to do with the CDI specification.

There are certainly ways how to improve the RCC API to make correct RCC usage easier. If we want to debate that, sure – I’m all for it.

1reaction
rmannibucaucommented, May 18, 2021

@Ladicek no issue with the callback since nested calls will return a noop callback, this is how start/stop context are generally implemented in servers.

I’m not sure what you meant with “all the necessary provisions are already there” but since activate/deactivate javadoc are not consistent, the behavior is not so we’ll break applications/usage by clarifying it so thought a new API can make it less ambiguous but if you think we should reuse the one we have and enforce deactivate to not be called when false is returned it can work too with some risk (and to be honest i’m not sure how low or high it is).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issues · jakartaee/cdi - GitHub
CDI specification. ... Add API to obtain current injection point from Bean#create ... RequestContextController spec impossible to implement.
Read more >
RequestContextController (Java(TM) EE 8 Specification APIs)
The CDI container provides a built in instance of RequestContextController that is dependent scoped for the purposes of activating and deactivating.
Read more >
JSR 365: Contexts and Dependency ... - Red Hat on GitHub
It is possible to implement generic beans that introspect the injection point to which they belong. This makes it possible to implement injection...
Read more >
News - Weld/CDI
Weld 3.0.0.Final - the first implementation of CDI 2.0! · Weld defines two non-portable notification options to configure the notification of asynchronous ...
Read more >
JSR 365: Contexts and Dependency ... - Software Download
Any use of the Specification and the information described therein ... Make possible to apply interceptor on producer in The ...
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