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 >