You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Paul Fremantle <pz...@gmail.com> on 2005/10/28 15:24:11 UTC

[Axis2] Implications of WSRM interfaces on Axis2 ClientAPI

I've been thinking about how Sandesha and Axis 2 should interact and how
people can code to Axis2 with the idea in mind that they might be reliable
later. I've just been asked a couple of times how can the code find out if a
message has been delivered.

This is an interesting issue. I used to believe it that RM shouldn't have
any impact on the Axis2 client api in normal usage, because I want to be
able to turn on or off WSRM without having to change my application code.

But there are some aspects that require some interaction with the
application. The first one is knowing how to associate messages with a
particular reliable sequence. For example, I may have multiple stubs running
in an application server on behalf of multiple clients. I could aggregate
all the requests into a single sequence, which will be more efficient in
terms of the protocol, and the overhead of managing large numbers of
sequences. But if the endpoint is doing ordered delivery, it now may end up
holding up messages from one client while messages for another are
delivered, which might not be the desired behaviour.

Sandesha uses a simple idea called a SequenceKey. The key is simply a marker
that the application code can use to help create the right underlying
sequences. If there are multiple stubs or Call objects that use the same
SequenceKey, then as long as they are targeted at the same endpoint,
Sandesha will aggregate them into the same sequence. On the other hand, if
you have two stubs with different SequenceKeys going to the same endpoint,
they will each have their own sequence.

I think this is a great model, it is simple and clean and effective. In fact
I think it is so good, that we should always code this way - even if we
aren't using RM yet. If the SequenceKey Constant was in the base Axis2
ClientAPI, we could code now with this in mind, so when we want RM, just
flick the switch. Of course if you don't set a SequenceKey, the Sandesha can
have a default behaviour.

The same applies to the idea of a LastMessage. Sandesha lets you mark a
message as being the last in a sequence. This is something that generally
only the application designer can know, so again I think it would be great
to promote the LastMessage constant onto the standard ClientAPI.

The final issue is letting the application know how the RM delivery is
getting on. In general we would like to trust that every message is
delivered successfully, but things happen. There will be occasions where
timeliness is also important. I see two potential approaches for this. The
first is to expose via a management interface a view of the whole sequence.
So in Java, we could make the sequence manageable via JMX. And if we make
the SequenceKey part of that management, then the application could use it
to help map from the application logic into the underlying sequence.

However, there is a more fundamental model, which is when I've made a
non-blocking call, I want to know whether that made it through. And in fact
this is something that is useful even without RM. Take a simple HTTP case:
if the call is truly non-blocking, it could execute the initial send on a
new thread, and then I will want to know whether there was an HTTP 202
return or some other. I may also want to know other information from a
non-blocking call - such as the messageId that was allocated to the outbound
message.

So this also seems to be a model we could promote to the base Call API in
Axis2 (and elsewhere).

Currently the Axis2 API is
void invokeNonBlocking(op, element, callback)

My suggestion is to add a new return parameter:
MessageTracker invokeNonBlocking(op, element, callback)

The MessageTracker would only track the outgoing message - the callback
object tracks the response.

A simple interface might be something like:
public interface MessageTracker {
public boolean isAcked();
public String getMessageID();
public boolean isReliable();
public boolean isUndeliverable();
}

The isAcked() is fairly clear. If this was a non-reliable interaction, this
would just indicate that there was a 202 from the server. In the reliable
instance this would indicate the message had been acked.

The isUndeliverable() would indicate that the message will never be
delivered. In the case of non-reliable, this would be where there was a
fault on the send. In the case of reliable, this would mean the sequence was
terminated or closed before this message was acked.

The isReliable() could be used to find out if some reliable messaging
standard is in use, to help make sense of the ack state.

And as I point out earlier, this could be useful even for non-reliable
requests, because we could make the nonBlocking call not even wait for the
request to be sent, and still track whether it succeeded.

Paul

PS This is a slightly modified version of a blog entry
http://www.bloglines.com/blog/paulfremantle?id=16