[jbossseam-issues] [JBoss JIRA] Commented: (JBSEAM-1918) Asyncronous methods called from an asyncronously executing methoed will not be invoke asyncronously

Anton Lyakishev (JIRA) jira-events at lists.jboss.org
Fri Feb 27 16:17:54 EST 2009


    [ https://jira.jboss.org/jira/browse/JBSEAM-1918?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12454780#action_12454780 ] 

Anton Lyakishev commented on JBSEAM-1918:
-----------------------------------------

There is still a problem: if you call a non-asynchronous method of an async component from an asynchronously executing method first, then a call to an asynchronous method will be executed synchronously.

I am proposing to change the following code (Seam 2.1.1 - AsynchronousInterceptor.java):

         if (isExecutingAsynchronousCall())
         {
            Contexts.getEventContext().set(REENTRANT, true);
         }
         try
         {
             return invocation.proceed();
         }
         finally
         {
             if (isExecutingAsynchronousCall())
             {
                 Contexts.getEventContext().remove(REENTRANT);
             }
         }

to the following:

         boolean flag_is_set = false;
         if (isExecutingAsynchronousCall() && !Contexts.getEventContext().isSet(REENTRANT))
         {
            Contexts.getEventContext().set(REENTRANT, true);
            flag_is_set = true;
         }
         try
         {
             return invocation.proceed();
         }
         finally
         {
             if (flag_is_set)
             {
                 Contexts.getEventContext().remove(REENTRANT);
             }
         }

to make sure we do not reset the REENTRANT flag if it was not set by us.

> Asyncronous methods called from an asyncronously executing methoed will not be invoke asyncronously
> ---------------------------------------------------------------------------------------------------
>
>                 Key: JBSEAM-1918
>                 URL: https://jira.jboss.org/jira/browse/JBSEAM-1918
>             Project: Seam
>          Issue Type: Bug
>          Components: Async
>    Affects Versions: 2.0.0.BETA1
>            Reporter: Chris Rudd
>            Assignee: Pete Muir
>             Fix For: 2.0.0.CR2
>
>
> 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();
>       }
>    }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list