Hi Dan,
Good advice, thanks! I was really only looking at this from the server
perspective as that's where the question arose, but you make the point about
the client having the exact same issue.
I solved the immediate problem using a method similar to your #2 suggestion ("a
couple of one-ways") and storing a non WS-A message id to handle the linking,
but as this problem has come up more than once recently I figured I'd better
ask you guys. I didn't use JMS, but the benefits are clear.
I like Dennis's WS-RM suggestion. I'm aware of it, and have tried sending
WS-RM messages using CXF, but am definitely not well-versed enough in its usage
to understand all the pros and cons.
Thanks,
Jesse
-----Original Message-----
From: Daniel Kulp [mailto:[email protected]]
Sent: Wednesday, November 20, 2013 1:51 PM
To: [email protected]; Jesse Pangburn
Subject: Re: long running asynchronous service provider
In general, once the message patterns become longer than about 30 seconds, I
would recommend completely rethinking the problem. It's no longer really a
request/reply style invocation and likely shouldn't be modeled as one. At
that point, I'd recommend one of a couple solutions:
1) Return an "id" from the initial post, then poll. Basically, the client
posts the request, the service does a quick validation of the request to make
sure it's valid and replies immediately with some sort of unique ID. The
client can then poll for the result, save the ID locally and continue polling
if the client has to shutdown/restart, etc... The client would have to be
careful not to poll too often to not flood the server, but it shouldn't require
much computing power no the server side to see if the response is ready or not.
2) Async based, but using something like JMS with a persistent store for the
transport. I'd likely even not use WS-Addressing for this to make the client
restart case much easier to implement. One of the actual parameters to the
service is the URL/JMS information to send the response to. When the client
starts up, it can connect to it's queue. If the queue is persistent, if the
server had sent a response already, it would be there. Fairly simple.
Everything is more or less modeled as a couple of one-ways for simplicity.
The JMS broker just makes sure the delivery is OK.
That said, WS-RM is there for this particular use case. I just haven't used
it much. I'd definitely defer to Dennis' and Aki's judgement and expertise for
information about that.
Dan
On Nov 20, 2013, at 1:34 PM, Jesse Pangburn <[email protected]> wrote:
> Hi,
> I use the jax-ws Provider mechanism to implement a service provider:
> @WebServiceProvider
> @ServiceMode(value = Service.Mode.MESSAGE) public class SOAPProvider
> implements Provider<StreamSource>
>
> If WS-Addressing is enabled and I receive a message with a ReplyTo address,
> then the server will automatically send back an immediate HTTP 202 to the
> request. When I finish computing a reply message and return it in a
> StreamSource (in this case), then CXF automatically makes a new HTTP request
> to the ReplyTo address and sends the reply there. This is the normal (and
> expected) asynchronous processing flow.
>
> It works, but it's not practical for a service that needs to reliably send
> reply messages to requests that it received. Suppose the service even
> processed the request for a minute- it's quite likely that a service will be
> interrupted by a server restart or something. The caller will never get
> their callback. Worse, what if the transactions run for days? And there are
> lots of them? This mechanism works for testing but is not production quality
> for anything that needs reliable responses.
>
> Is there a mechanism I'm missing for storing these transactions to a database
> or something, and putting the response processing in a separate thread as
> well? Some way to make asynchronous transactions reliable?
>
> Thanks,
> Jesse
--
Daniel Kulp
[email protected] - http://dankulp.com/blog Talend Community Coder -
http://coders.talend.com