<div dir="ltr">@arjan Your example is base on <span style="font-size:13px"> ManagedExecutorService from the Java EE Concurrency spec. That&#39;s one topic we&#39;ve been wondering about : should the @Asynchronous interceptor go to the Java EE Concurrency spec or not ? But it looks like the spec might not be updated.</span><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">Antonio</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 17, 2015 at 12:32 AM, arjan tijms <span dir="ltr">&lt;<a href="mailto:arjan.tijms@gmail.com" target="_blank">arjan.tijms@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">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></span><div>That&#39;s quite a coincidence, it&#39;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&#39;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&#39;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><div class="h5"><div><br></div><div><br></div><div> </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><br>
    <br>
    <div>On 01/16/2015 06:17 PM, arjan tijms
      wrote:<br>
    </div>
    </div></div><blockquote type="cite"><div><div>
      <div dir="ltr">
        <div>
          <div>Hi,<br>
            <br>
          </div>
          I&#39;m attempting to emulate EJB&#39;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>
              private static final long serialVersionUID = 1L;<br>
              <br>
              @Resource<br>
              private ManagedExecutorService managedExecutorService;<br>
          <br>
              @AroundInvoke<br>
              public Object submitAsync(InvocationContext ctx) throws
          Exception {<br>
                  return new
          FutureDelegator(managedExecutorService.submit( ()-&gt; {
          return ctx.proceed(); } ));<br>
              }<br>
          <br>
          }<br>
          <br>
        </div>
        <div>With FutureDelegator as follows:<br>
          <br>
          public class FutureDelegator implements Future&lt;Object&gt; {<br>
              <br>
              private Future&lt;?&gt; future;<br>
              <br>
              public FutureDelegator(Future&lt;?&gt; future) {<br>
                  this.future = future;<br>
              }<br>
          <br>
              @Override<br>
              public Object get() throws InterruptedException,
          ExecutionException {<br>
                  AsyncResult&lt;?&gt; asyncResult =
          (AsyncResult&lt;?&gt;) future.get();<br>
                  if (asyncResult == null) {<br>
                      return null;<br>
                  }<br>
                  <br>
                  return asyncResult.get(); <br>
              }<br>
              <br>
              @Override<br>
              public Object get(long timeout, TimeUnit unit) throws
          InterruptedException,    ExecutionException, TimeoutException
          {<br>
                  AsyncResult&lt;?&gt; asyncResult =
          (AsyncResult&lt;?&gt;) future.get(timeout, unit);<br>
                  if (asyncResult == null) {<br>
                      return null;<br>
                  }<br>
                  <br>
                  return asyncResult.get(); <br>
              }<br>
              <br>
              @Override<br>
              public boolean cancel(boolean mayInterruptIfRunning) {<br>
                  return future.cancel(mayInterruptIfRunning);<br>
              }<br>
              <br>
              @Override<br>
              public boolean isCancelled() {<br>
                  return future.isCancelled();<br>
              }<br>
              @Override<br>
              public boolean isDone() {<br>
                  return future.isDone();<br>
              }<br>
              <br>
          }<br>
          <br>
        </div>
        <div>This of course didn&#39;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>
              private static final long serialVersionUID = 1L;<br>
              <br>
              @Resource<br>
              private ManagedExecutorService managedExecutorService;<br>
              <br>
              private static final ThreadLocal&lt;Boolean&gt;
          asyncInvocation = new ThreadLocal&lt;Boolean&gt;();<br>
          <br>
              @AroundInvoke<br>
              public synchronized Object submitAsync(InvocationContext
          ctx) throws Exception {<br>
                  <br>
                  if (TRUE.equals(asyncInvocation.get())) {<br>
                      return ctx.proceed();<br>
                  }<br>
                  <br>
                  return new
          FutureDelegator(managedExecutorService.submit( ()-&gt; { <br>
                      try {<br>
                          asyncInvocation.set(TRUE);<br>
                          return ctx.proceed();<br>
                      } finally {<br>
                           asyncInvocation.remove();<br>
                      }<br>
                  }));<br>
              }<br>
          <br>
          }<br>
          <br>
        </div>
        <div>But I&#39;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&#39;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></div></div><br></div></div>
<br>_______________________________________________<br>
cdi-dev mailing list<br>
<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
<br>
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.<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Antonio Goncalves <br>Software architect, Java Champion and Pluralsight author<br><br><a href="http://www.antoniogoncalves.org" target="_blank">Web site</a> | <a href="http://twitter.com/agoncal" target="_blank">Twitter</a> | <a href="http://www.linkedin.com/in/agoncal" target="_blank">LinkedIn</a> | <a href="http://pluralsight.com/training/Authors/Details/antonio-goncalves" target="_blank">Pluralsight</a> | <a href="http://www.parisjug.org" target="_blank">Paris JUG</a> | <a href="http://www.devoxx.fr" target="_blank">Devoxx France</a></div></div>
</div>