Uploaded image for project: 'Seam 2'
  1. Seam 2
  2. JBSEAM-1918

Asyncronous methods called from an asyncronously executing methoed will not be invoke asyncronously

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 2.0.0.BETA1
    • Fix Version/s: 2.0.0.CR2
    • Component/s: Async
    • Labels:
      None

      Description

      Currently the AsyncronousInterceptor triggers off of
      Contexts.getEventContext().isSet(AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL)
      to determine if this invocation was from the asyncronous dispatcher. This works fine, except under the conditions where the asyncronously executed method calls another @asyncronous methd. In that case the Event context alreadt contains the AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL marked and the execution is done immedialty instead of being scheduled.

      I belive a simple resolution would be to have the AsyncronousInterceptor clear the AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL before proceeding with the exection, but should only be done if the method in question is an @Asycnronous method. This would be to elimiate possible removal from other components that are called during the process of invoking the asyncronous method (ie injection, security, etc).

      Here is me proposed change :

      AsyncronousInterceptor.java line 24

      @AroundInvoke
      public Object aroundInvoke(InvocationContext invocation) throws Exception
      {
      boolean scheduleAsync = invocation.getMethod().isAnnotationPresent(Asynchronous.class) &&
      !Contexts.getEventContext().isSet(AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL);
      if (scheduleAsync)
      {
      Dispatcher dispatcher = AbstractDispatcher.instance();
      if (dispatcher==null)

      { throw new IllegalStateException("org.jboss.seam.async.dispatcher is not installed in components.xml"); }

      Object timer = dispatcher.scheduleInvocation( invocation, getComponent() );
      //if the method returns a Timer, return it to the client
      return timer!=null && invocation.getMethod().getReturnType().isAssignableFrom( timer.getClass() ) ? timer : null;
      }
      + else if( invocation.getMethod().isAnnotationPresent(Asynchronous.class) )
      +

      { + // Clear the async flag so that any async methods called by this invocation will execute asyncronously + Contexts.getEventContext().remove( AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL ); + return invocation.proceed(); + }

      else

      { return invocation.proceed(); }

      }

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  pmuir Pete Muir
                  Reporter:
                  cmrudd Chris Rudd
                • Votes:
                  1 Vote for this issue
                  Watchers:
                  0 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: