2 Replies Latest reply on Oct 21, 2012 5:44 PM by matlach

    hack @asynchronous implementation

    matlach

      I'd really like to implement an @Asynchronous interceptor like :

       

      @Asynchronous
      @Interceptor
      public class AsynchronousInterceptor
      {
      
          @Inject
          private AsynchronousService asynchronousService;
          
          @AroundInvoke 
          public Object runAsync(final InvocationContext ctx) throws Exception
          {
              asynchronousService.submit(new Callable<Void>(){
                  @Override
                  public Void call() throws Exception
                  {
                      ctx.proceed();
                      return null;
                  }});        
              return null;
          }
      }
      
      

       

      I'm aware of the https://issues.jboss.org/browse/WELD-862 issue but... I'd really like to implement it.

      I'm not looking for a neat implementation, just an hack (if possible) and will deal with the limitations.

       

      So far I have try with reflection :

      - to increment the InterceptorInvocationContext interceptionChain position

      - to duplicate the InterceptionDecorationContext interceptionContexts ThreadLocal

      but nothing worked out.

       

      I think I might just need some guideline or ideas.

      Anyone could help me out find a workaround for this ?

       

      Big thanks,

        • 1. Re: hack @asynchronous implementation
          alesj

          A quick idea from the top of my head ... might not work.

           

          (1) Make sure this interceptor is the first, ignore async logic if ThreadLocal from (3) is set.

          (2) Then gather target information from existing InvocationContext - target, method, params, ...

          (3) In Callable::call setup a ThreadLocal, invoke target with method, params, reset ThreadLocal.

           

          Let me know if it works. :-)

          • 2. Re: hack @asynchronous implementation
            matlach

            you're a genius Ales !

             

            this works flawlessy :

             

            @Asynchronous
            @Interceptor
            public class AsynchronousInterceptor
            {
            
                private static ThreadLocal<Object> hack = new ThreadLocal<Object>();
                
                @Inject
                private AsynchronousService asynchronousService;
                
                @AroundInvoke 
                public Object runAsync(final InvocationContext ctx) throws Exception
                {
                    // we assume AsynchronousInterceptor is the first in chain
                    if (hack.get() == null)
                    {
                        asynchronousService.submit(new Callable<Void>(){
                            @Override
                            public Void call() throws Exception
                            {
                                hack.set(new Object());
                                try
                                {
                                    ctx.getMethod().invoke(ctx.getTarget(), ctx.getParameters());
                                }
                                finally
                                {
                                    hack.remove();
                                }
                                return null;
                            }});
                    }
                    else
                    {
                        ctx.proceed();
                    }
                    return null;
                }
            
            }