<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif;">
<div>
<div>
<div>Hi Arjan,</div>
</div>
</div>
<div><br>
</div>
<div>Since we almost don’t use ThreadLocals in OWB, I guess, this should work out of the box.</div>
<div>Did a quick check of the interceptor code and see no issues with handling over the InvocationContext to another thread. However, the InvocationContext has some internal state that could get confused, if proceed() is called in parallel from two different
 threads, but that’s another thing. Just give it a try and tell us about the result :-)</div>
<div><br>
</div>
<div>Cheers,</div>
<div>Arne</div>
<div><br>
</div>
<span id="OLK_SRC_BODY_SECTION">
<div style="font-family:Calibri; font-size:11pt; text-align:left; color:black; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0in; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; BORDER-TOP: #b5c4df 1pt solid; BORDER-RIGHT: medium none; PADDING-TOP: 3pt">
<span style="font-weight:bold">Von: </span>arjan tijms &lt;<a href="mailto:arjan.tijms@gmail.com">arjan.tijms@gmail.com</a>&gt;<br>
<span style="font-weight:bold">Datum: </span>Samstag, 17. Januar 2015 00:32<br>
<span style="font-weight:bold">An: </span>Jozef Hartinger &lt;<a href="mailto:jharting@redhat.com">jharting@redhat.com</a>&gt;<br>
<span style="font-weight:bold">Cc: </span>&quot;<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a>&quot; &lt;<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a>&gt;<br>
<span style="font-weight:bold">Betreff: </span>Re: [cdi-dev] Building EJB-like @Asynchronous via interceptor in CDI<br>
</div>
<div><br>
</div>
<div>
<div>
<div dir="ltr">Hi,<br>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Fri, Jan 16, 2015 at 10:41 PM, Jozef Hartinger <span dir="ltr">
&lt;<a href="mailto:jharting@redhat.com" target="_blank">jharting@redhat.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF">Hi Arjan,<br>
<br>
I did some changes recently in Weld interceptors and this usecase now works smoothly. The code is not part of a release yet. See this test for a simple implementation of an @Async interceptor (basically the same as your initial attempt). Note that the chain
 is repeatable but at the same time it is not reset after dispatch to a different thread so you no longer need the ThreadLocal nor any other workaround.<br>
</div>
</blockquote>
<div><br>
</div>
<div>That's quite a coincidence, it's indeed rather similar ;)</div>
<div><br>
</div>
<div>I wonder how it now works though, as the InvocationContext &quot;ctx&quot; does not seem to be made aware that it's been dispatched to a different thread from within the code. Does it use an internal thread local to keep state or so?</div>
<div><br>
</div>
<div>I'll also try to see what this does on OWB. Do you think this is something that should work, or just something that Weld happens to support regardless of the spec?</div>
<div><br>
</div>
<div>Kind regards,</div>
<div>Arjan</div>
<div><br>
</div>
<div><br>
</div>
<div>&nbsp;</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF"><br>
<a href="https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/thread/async/AsyncInterceptor.java" target="_blank">https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/interceptors/thread/async/AsyncInterceptor.java</a><br>
<br>
Jozef
<div>
<div class="h5"><br>
<br>
<div>On 01/16/2015 06:17 PM, arjan tijms wrote:<br>
</div>
</div>
</div>
<blockquote type="cite">
<div>
<div class="h5">
<div dir="ltr">
<div>
<div>Hi,<br>
<br>
</div>
I'm attempting to emulate EJB's @Asynchronous in CDI using interceptors.<br>
<br>
Originally I had defined my interceptor as follows;<br>
<br>
@Interceptor<br>
@Asynchronous<br>
@Priority(APPLICATION)<br>
public class AsynchronousInterceptor implements Serializable {<br>
<br>
&nbsp;&nbsp;&nbsp; private static final long serialVersionUID = 1L;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; @Resource<br>
&nbsp;&nbsp;&nbsp; private ManagedExecutorService managedExecutorService;<br>
<br>
&nbsp;&nbsp;&nbsp; @AroundInvoke<br>
&nbsp;&nbsp;&nbsp; public Object submitAsync(InvocationContext ctx) throws Exception {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return new FutureDelegator(managedExecutorService.submit( ()-&gt; { return ctx.proceed(); } ));<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
}<br>
<br>
</div>
<div>With FutureDelegator as follows:<br>
<br>
public class FutureDelegator implements Future&lt;Object&gt; {<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; private Future&lt;?&gt; future;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; public FutureDelegator(Future&lt;?&gt; future) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.future = future;<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp; @Override<br>
&nbsp;&nbsp;&nbsp; public Object get() throws InterruptedException, ExecutionException {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AsyncResult&lt;?&gt; asyncResult = (AsyncResult&lt;?&gt;) future.get();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (asyncResult == null) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return null;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return asyncResult.get(); <br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; @Override<br>
&nbsp;&nbsp;&nbsp; public Object get(long timeout, TimeUnit unit) throws InterruptedException,&nbsp;&nbsp;&nbsp; ExecutionException, TimeoutException {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AsyncResult&lt;?&gt; asyncResult = (AsyncResult&lt;?&gt;) future.get(timeout, unit);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (asyncResult == null) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return null;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return asyncResult.get(); <br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; @Override<br>
&nbsp;&nbsp;&nbsp; public boolean cancel(boolean mayInterruptIfRunning) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return future.cancel(mayInterruptIfRunning);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; @Override<br>
&nbsp;&nbsp;&nbsp; public boolean isCancelled() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return future.isCancelled();<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; @Override<br>
&nbsp;&nbsp;&nbsp; public boolean isDone() {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return future.isDone();<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; <br>
}<br>
<br>
</div>
<div>This of course didn't quite work, as the InvocationContext will be reset after the @AroundInvoke method returns, and an infinite intercept loop results (on Weld).<br>
<br>
I got it to work though on Weld by using a thread local check to break that loop:<br>
<br>
@Interceptor<br>
@Asynchronous<br>
@Priority(PLATFORM_BEFORE)<br>
public class AsynchronousInterceptor implements Serializable {<br>
<br>
&nbsp;&nbsp;&nbsp; private static final long serialVersionUID = 1L;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; @Resource<br>
&nbsp;&nbsp;&nbsp; private ManagedExecutorService managedExecutorService;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; private static final ThreadLocal&lt;Boolean&gt; asyncInvocation = new ThreadLocal&lt;Boolean&gt;();<br>
<br>
&nbsp;&nbsp;&nbsp; @AroundInvoke<br>
&nbsp;&nbsp;&nbsp; public synchronized Object submitAsync(InvocationContext ctx) throws Exception {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (TRUE.equals(asyncInvocation.get())) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return ctx.proceed();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return new FutureDelegator(managedExecutorService.submit( ()-&gt; { <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; asyncInvocation.set(TRUE);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return ctx.proceed();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } finally {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;asyncInvocation.remove();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }));<br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
}<br>
<br>
</div>
<div>But I've got a feeling this works just by chance and not because the workaround is so clever.<br>
<br>
</div>
<div>What do you guys think, what would be the best way to support this with the current CDI version? Or would CDI/Interceptors need something like Servlet's async support, where the InvocationContext is put into async mode whereafter it &quot;simply&quot; allows an
 other thread to continue processing on it?<br>
<br>
</div>
<div>Kind regards,<br>
Arjan Tijms<br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
<br>
</div>
</div>
<br>
<fieldset></fieldset> <br>
</div>
</div>
<pre>_______________________________________________
cdi-dev mailing list
<a href="mailto:cdi-dev@lists.jboss.org" target="_blank">cdi-dev@lists.jboss.org</a><a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a>

Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.</pre>
</blockquote>
<br>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</div>
</span>
</body>
</html>