----- Original Message -----
Sent: Saturday, January 07, 2006 11:56
PM
Subject: Re: [Sandesha2] Acknowledging
policy
Hi Jaliya, All,
See my comments below
-----
Original Message -----
Sent:
Friday, January 06, 2006 3:06 AM
Subject:
[Sandesha2] Acknowledging policy
Hi All,
It seems like we need to do some adjustments to our
acknowledging policy.
Currently acknowledging incoming application
messages is done by the SandeshaInHandler. So acknowledging happens before
the message is actually delivered to the service.
>>But the message is received by the
RMEndpoint and that means we should acknowledge.
But it seems like we can provide a
better quality reliability by not acknowledging till we actually invoke
the service. This way we can guarantee the delivering of the message to
the service even in the in-memory case. (I.e. if the client receive an ack
he can be sure that the service got actually invoked).
>>Yes, but the problem is once the
message is received by the RMEndpoint it is RMEndpoints responsibility to
invoke the web service. So what we want >>is to improve the
reliability of the RMEndpoint.
>>IMHO we should not expect the initial
sender to wait till the web service gets invoked for an
acknowledgment.
>>Consider a scenario where we have 3
messages and the RMEndpoint manager in the destination receive 2 and 3 but
not 1. We use INORDER >>invocation. Now we will not acknowledge for
any of the messages since we did not receive message 1. This is not
correct, because then the >>RMEndpoint manager in the client side
will keep on sending all the 3 messages again and
again.
yes, But if the server sends the messages and fail before he
actually invoke the service, the client will proceed believing that the
service got actually invoked. It is not important weather the message got lost
in the wire, or it got lost within the server, the result is the same (the
service did not get invoked). So the result is equal to acknowledging a
message the server did not receive.
But performance wise what you say is very correct. If the server consume
a long time to invoke the service, the client will also have to wait a long
time for an acknowledgement.
Your point is correct, but can we generalize this
to suite all the cases?
Say we acknowledge the only when the service gets
invoked, but if the service takes a long time to complete then we are waiting
unnecessarily for acknowledgements.
It can be a option in Sandesha but it should not
be the default case. Many people worry about the message losses than the
failover so we have to support the common case efficiently.
If someone needs failover recovery then he should
definitely go for a better solution like persistence Sandesha. Even if we
acknowledge messages when they actually handed over to the service, we cannot
get the reliability as per the persistence case, so IMHO we should
not worry about providing another halfway persistence option sacrificing
the performance.
Now an interesting problem arises when we consider the implementation
of the above scenario. Suppose a message arrives to an RM enabled In-Only
operation. Now SandeshaOutHandler does not get called and we have to send
the ack within the in-path. How can we do something after invocation
within the in-path. Here is one way,
Currently we do
in-order invocation using the InOrderInvoker thread. Within the
SandeshaInHandler we pause the messages, and the InOrderInvoker resumes
them in the correct order. If we make this thread the Invoker for all the
messages and if we move the ack sending logic into this, we can accomplish
above (basically we will pause all the incoming messages and we will send
the ack only after the Invoker thread resumes the message).
But
when we consider the current implementation of the pause functionality of
Axis2 there is again a slight problem. When pause is called the incoming
thread simply returns. So we have to add the ack before pausing if the
acksTo endpoint is the anonymous URL.
Considering all of the above
points I thought we can go for the policy given below.
1. Sandesa2
will always use the Invoker thread to invoke messages. All incoming
request messages will be paused in the request path and they will be
resumed by the Invoker thread.
2. If the acksTo endpoint is
anonymous Sandesha2 will send the acknowledgement within the
SandeshaInHandler (before actually invoking the service.)
3. If the
user has given an actual acksTo endpoint. Sandesha2 will make sure that it
only acknowledges messages after the invocation.
>>I think we should have a consistent
acknowledgement mechanism in all the
cases.
Agree.But I feel it is consistent enough. We can clearly say that the
client can get a better quality reliability (even in the in-memory case) if he
specify a true acksTo endpoint (let's document this well :-) ). I feel it is
better than giving a lower quality in both cases.
I don't think we give a lower quality
product. These are two different problems we try to solve. One is
reliability over the wire and the failover recovery. We have solutions
for both in Sandesha (once we have persistence version out)
Remember that I'm only talking about the in-memory scenarios here. If
the user go for permanent storage based reliability, invocation of acked
messages will always be guaranteed (using message re-injection).
>>Let's try to get this working. So we
have the maximum reliability :)
It is already working. But the
prob is code is dependent on Hibernate so I'm not able
to commit the permanent storage pluging. I'll try to create another
plugin using Apache JDO.
Let's wait till the license thingy gets
solved.
Cool, +1 for JDO.