hi folks!

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. My original impl was 
of course wrong. The 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).

Wdyt?
Gonna open a ticket in the spec.

LieGrue,
strub

Reply via email to