Hi,
On Sat, Jan 17, 2015 at 11:05 AM, Antonio Goncalves <
antonio.goncalves(a)gmail.com> wrote:
@arjan Your example is base on ManagedExecutorService from the Java
EE
Concurrency spec. That's one topic we'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.
The example I showed here would IMHO best be placed in the Java EE
Concurrency spec. That would in my opinion be a perfect analogy to
@Transactional and JTA. As given, the interceptor uses CDI/Interceptors and
Concurrency, so theoretically it could also be put into a third spec.
Personally I would find it strange to put something in spec A, when it may
better belong in spec B, just because spec B is not updated. What's holding
the update of Java EE Concurrency back? If most of the EG members would be
of the opinion that an @Asynchronous interceptor belongs best in Java EE
Concurrency, then we can just update that spec, right?
I know that MR releases can be quite fast and agile process wise, while
still packing some punch. JTA 1.2 itself was just such an MR, and JASPIC
1.1 was too. I was somewhat involved with JASPIC 1.1 (as community member)
and I think the setup time was pretty fast. Mid feb 2013 we created the
JIRA issues, the MR draft was published early march 2013 and the release
was with EE 7 end may 2013.
If it would just be about putting a few interceptors formally in Java EE
Concurrency, then why not do such small update for it?
Kind regards,
Arjan
Antonio
On Sat, Jan 17, 2015 at 12:32 AM, arjan tijms <arjan.tijms(a)gmail.com>
wrote:
> Hi,
>
> On Fri, Jan 16, 2015 at 10:41 PM, Jozef Hartinger <jharting(a)redhat.com>
> wrote:
>
>> Hi Arjan,
>>
>> 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.
>>
>
> That's quite a coincidence, it's indeed rather similar ;)
>
> I wonder how it now works though, as the InvocationContext "ctx" 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?
>
> 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?
>
> Kind regards,
> Arjan
>
>
>
>
>>
>>
>>
https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/o...
>>
>> Jozef
>>
>>
>> On 01/16/2015 06:17 PM, arjan tijms wrote:
>>
>> Hi,
>>
>> I'm attempting to emulate EJB's @Asynchronous in CDI using
interceptors.
>>
>> Originally I had defined my interceptor as follows;
>>
>> @Interceptor
>> @Asynchronous
>> @Priority(APPLICATION)
>> public class AsynchronousInterceptor implements Serializable {
>>
>> private static final long serialVersionUID = 1L;
>>
>> @Resource
>> private ManagedExecutorService managedExecutorService;
>>
>> @AroundInvoke
>> public Object submitAsync(InvocationContext ctx) throws Exception {
>> return new FutureDelegator(managedExecutorService.submit( ()-> {
>> return ctx.proceed(); } ));
>> }
>>
>> }
>>
>> With FutureDelegator as follows:
>>
>> public class FutureDelegator implements Future<Object> {
>>
>> private Future<?> future;
>>
>> public FutureDelegator(Future<?> future) {
>> this.future = future;
>> }
>>
>> @Override
>> public Object get() throws InterruptedException, ExecutionException {
>> AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
>> if (asyncResult == null) {
>> return null;
>> }
>>
>> return asyncResult.get();
>> }
>>
>> @Override
>> public Object get(long timeout, TimeUnit unit) throws
>> InterruptedException, ExecutionException, TimeoutException {
>> AsyncResult<?> asyncResult = (AsyncResult<?>)
>> future.get(timeout, unit);
>> if (asyncResult == null) {
>> return null;
>> }
>>
>> return asyncResult.get();
>> }
>>
>> @Override
>> public boolean cancel(boolean mayInterruptIfRunning) {
>> return future.cancel(mayInterruptIfRunning);
>> }
>>
>> @Override
>> public boolean isCancelled() {
>> return future.isCancelled();
>> }
>> @Override
>> public boolean isDone() {
>> return future.isDone();
>> }
>>
>> }
>>
>> 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).
>>
>> I got it to work though on Weld by using a thread local check to break
>> that loop:
>>
>> @Interceptor
>> @Asynchronous
>> @Priority(PLATFORM_BEFORE)
>> public class AsynchronousInterceptor implements Serializable {
>>
>> private static final long serialVersionUID = 1L;
>>
>> @Resource
>> private ManagedExecutorService managedExecutorService;
>>
>> private static final ThreadLocal<Boolean> asyncInvocation = new
>> ThreadLocal<Boolean>();
>>
>> @AroundInvoke
>> public synchronized Object submitAsync(InvocationContext ctx) throws
>> Exception {
>>
>> if (TRUE.equals(asyncInvocation.get())) {
>> return ctx.proceed();
>> }
>>
>> return new FutureDelegator(managedExecutorService.submit( ()-> {
>> try {
>> asyncInvocation.set(TRUE);
>> return ctx.proceed();
>> } finally {
>> asyncInvocation.remove();
>> }
>> }));
>> }
>>
>> }
>>
>> But I've got a feeling this works just by chance and not because the
>> workaround is so clever.
>>
>> 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 "simply" allows an other thread to continue processing on
it?
>>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> cdi-dev mailing
listcdi-dev@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/cdi-dev
>>
>> Note that for all code provided on this list, the provider licenses the code
under the Apache License, Version 2 (
http://www.apache.org/licenses/LICENSE-2.0.html). For
all other ideas provided on this list, the provider waives all patent and other
intellectual property rights inherent in such information.
>>
>>
>>
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the
> code under the Apache License, Version 2 (
>
http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
> provided on this list, the provider waives all patent and other
> intellectual property rights inherent in such information.
>
--
Antonio Goncalves
Software architect, Java Champion and Pluralsight author
Web site <
http://www.antoniogoncalves.org> | Twitter
<
http://twitter.com/agoncal> | LinkedIn
<
http://www.linkedin.com/in/agoncal> | Pluralsight
<
http://pluralsight.com/training/Authors/Details/antonio-goncalves> | Paris
JUG <
http://www.parisjug.org> | Devoxx France <
http://www.devoxx.fr>