Hi Mark,

for case a), would an AtomicInteger work as well (instead of boolean
didActivate)? This way you could deactivate for each activate() call.

Am Di., 18. Mai 2021 um 07:19 Uhr schrieb Mark Struberg
<strub...@yahoo.de.invalid>:
>
> 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