Sorry for the delay Bill.

+1 to your solution. However I'd personally prefer if you change the
return type to be boolean: true means paused and false means all is
cool.

I'm very wary of executing thing change right now because it'll break
all downstream projects including Rahas/Rampart/Sandesha/Synapse etc.
which have not cut 1.1 branches. We definitely want them to run on Axis2
1.1 and so its necessary to not change them. Is there any way to wait
until we get back onto one trunk?

Or maybe the right answer is for those projects to branch too now.

Thoughts?

Sanjiva.

On Tue, 2006-10-17 at 06:39 -0700, Bill Nagy wrote:
> Do you still have an objection to this Sanjiva?
> 
> -Bill
> 
> On Tue, 2006-10-10 at 18:20 -0700, Bill Nagy wrote:
> > Hi Sanjiva,
> > 
> > The problem isn't that both people are modifying MessageContext.paused,
> > so synchronizing that isn't going to work, the problem is that if the RM
> > handler, for instance, pauses the message and returns, but the RM thread
> > picks up the message and resumes it (thereby unpausing the message)
> > before control returns to the logic in the Phase/AxisEngine, the
> > Phase/AxisEngine are going to proceed as if the message was never
> > paused.
> > 
> > I was trying to avoid the overhead of synchronization when we have
> > another solution that works just as well (i.e. the return value) without
> > the overhead (and is more logically correct IMO.)
> > 
> > Using the return code also allows us to capture whether or not a message
> > was 'paused' vs 'aborted' -- this is important in the handler unwinding,
> > as no unwinding needs to occur in the 'paused' case while it does in the
> > 'aborted' case.
> > 
> > I prefer an enumeration object because it's clear from the method
> > signature what is being returned (InvocationProcessingInstruction vs.
> > int in this case,) but if that's all that is holding you up, I'll switch
> > it to constants.
> > 
> > -Bill
> > 
> > On Tue, 2006-10-10 at 18:13 +0530, Sanjiva Weerawarana wrote: 
> > > On Mon, 2006-10-09 at 19:51 -0700, Bill Nagy wrote:
> > > > There is currently a race condition between code that pauses the message
> > > > flow within a handler and resumes it on another thread (e.g. Sandesha)
> > > > and the message flow processing chain (Phase.invoke(...),
> > > > AxisEngine.invoke(...), etc.)
> > > > (http://issues.apache.org/jira/browse/SANDESHA2-32)  This is caused
> > > > because the control of processing is keyed off of MessageContext.paused
> > > > and not through some other mechanism (return code, semaphore, etc.).  If
> > > > a handler pauses a message and returns, handing the message off to
> > > > another thread for execution, there is the possibility that the new
> > > > execution thread will resume processing of the message, unsetting
> > > > MessageContext.paused, before control returns to one of the invoke
> > > > methods.  If this happens, the logic in the invoke method, which looks
> > > > at the MessageContext.paused flag, will believe that it should continue
> > > > execution instead of halting.
> > > 
> > > Can't this be solved by synchronizing access to MessageContext.paused()?
> > > Sorry I looked at the sandesha issue but didn't see it.
> > > 
> > > Alternatively,
> > > 
> > > synchronized {
> > >   h.invoke();
> > >   h.getPaused();
> > > }
> > > 
> > > I must be missing something obvious as to why this doesn't work.
> > > 
> > > > Since the problem revolves around flow control logic, I suggest that we
> > > > use the return code from the method invocation to deal with it.  I would
> > > > like to add a return code to the Handler.invoke(...) which would
> > > > identify how processing of the message should proceed, e.g. :
> > > 
> > > How does this solve the problem as other thread could go get the MC and
> > > do stuff while still in this method? 
> > > 
> > > > /**
> > > > * This type encapsulates an enumeration of possible message processing
> > > > * instruction values that may be returned by a handler/phase within the
> > > > * runtime.
> > > > */
> > > > public class InvocationProcessingInstruction
> > > > {
> > > >   public static InvocationProcessingInstruction CONTINUE_PROCESSING =
> > > > new InvocationProcessingInstruction(0);
> > > >   public static InvocationProcessingInstruction SUSPEND_PROCESSING = new
> > > > InvocationProcessingInstruction(1);
> > > >   public static InvocationProcessingInstruction ABORT_PROCESSING = new
> > > > InvocationProcessingInstruction(2);
> > > >   
> > > >   private int instructionID;
> > > >     
> > > >   private InvocationProcessingInstruction(int instructionID)
> > > >   {
> > > >     this.instructionID = instructionID;
> > > >   }
> > > >     
> > > >   public boolean equals(InvocationProcessingInstruction instruction)
> > > >   {
> > > >     return this.instructionID == instruction.instructionID;
> > > >   }
> > > >     
> > > >   public int hashCode()
> > > >   {
> > > >     return instructionID;
> > > >   }
> > > > }
> > > > 
> > > > Most handlers will return
> > > > InvocationProcessingInstruction.CONTINUE_PROCESSING; the RM handler may
> > > > return that, SUSPEND_PROCESSING (for a pause), or ABORT_PROCESSING (for
> > > > a duplicate msg.)
> > > 
> > > I must be really jetlagged (traveling again): do we need all this or
> > > just use an int to return the status?? (some consts basically).
> > > 
> > > Sanjiva.
> > > 
> > > 
> > > 
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > For additional commands, e-mail: [EMAIL PROTECTED]
> > 
> > 
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to