You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Daniel Kulp <dk...@apache.org> on 2008/10/23 16:14:33 UTC
JMS transport sync/async......
Christian,
When you get some time, can you look at what I've done in the JMS transport to
make sure it's all OK and doesn't introduce some massive scalability issue?
Basically, I now call the message observer directly from the
onMessage(JMSMessage) call. This means its called on the thread that the
JMS queue provides instead of from the CXF calling thread. Right now, if
it's a synchronous invoke, I left the "wait()" in place on the main thread,
but that's really not needed. It could return immediately as the
ClientImpl will then wait if it's supposed to be synchronous. I mostly left
it there due to the jmsTemplate.getReceiveTimeout() thing. If we return,
the timeout would need to be configured on the client itself, which might
not be a bad thing. Not really sure. Maybe the default could be
RECEIVE_TIMEOUT_NO_WAIT and only wait on that main thread if it's set
otherwise? I don't really know, not my area of expertise.
I guess my main concern is if it's OK to process the response on the JMS
provided thread. Is that part of a thread pool or similar? If not, we'll
need to throw it on a workqueue. That's easy enough to do, but I wanted to
hear from you first.
Thanks!
--
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Re: JMS transport sync/async......
Posted by Christian Schneider <ch...@die-schneider.net>.
Hi Dan,
I will look into the async code on the weekend. Like you said the main
problem could be how to handle the separate thread
of the message handler.
Greetings
Christian
Daniel Kulp schrieb:
> Christian,
>
> When you get some time, can you look at what I've done in the JMS transport to
> make sure it's all OK and doesn't introduce some massive scalability issue?
>
> Basically, I now call the message observer directly from the
> onMessage(JMSMessage) call. This means its called on the thread that the
> JMS queue provides instead of from the CXF calling thread. Right now, if
> it's a synchronous invoke, I left the "wait()" in place on the main thread,
> but that's really not needed. It could return immediately as the
> ClientImpl will then wait if it's supposed to be synchronous. I mostly left
> it there due to the jmsTemplate.getReceiveTimeout() thing. If we return,
> the timeout would need to be configured on the client itself, which might
> not be a bad thing. Not really sure. Maybe the default could be
> RECEIVE_TIMEOUT_NO_WAIT and only wait on that main thread if it's set
> otherwise? I don't really know, not my area of expertise.
>
> I guess my main concern is if it's OK to process the response on the JMS
> provided thread. Is that part of a thread pool or similar? If not, we'll
> need to throw it on a workqueue. That's easy enough to do, but I wanted to
> hear from you first.
>
> Thanks!
>
--
Christian Schneider
---
http://www.liquid-reality.de
Re: JMS transport sync/async......
Posted by Daniel Kulp <dk...@apache.org>.
On Monday 27 October 2008 2:02:14 pm Christian Schneider wrote:
> Daniel Kulp schrieb:
> > It could, but HTTP and CORBA performance would certainly suffer and the
> > number of threads blocked on requests in the sync cases would double.
> > Since part of what I'm trying to do is eliminate/reduce the number of
> > blocked threads, that would be bad. Basically, if a request is known
> > to be synchronous, if the transports can do everything on the single
> > thread, that's greatly preferred. Otherwise, you have the ClientImpl
> > blocking as well as a background thread blocking for the transport.
> > (along with all the context switches and such to flip threads through the
> > CPU)
>
> I don´t think that this has to be the case. An async http request could
> send the request and store the http session in the message.
> Then it could return. The client would then call another function to
> wait for the response. I am not yet sure how this could work but I will
> try to work out something that works equally well with http and jms.
I'm not sure this is possible without changing the API of the conduit which
isn't something we can due to compatibility with out of tree transports.
(mule, smx, etc...) If you can do it, great. :-)
> > I think the client calls into the Conduit with a "done" message or
> > something at the end. The JMS conduit should be able to do any cleanup
> > there: getConduitSelector().complete(exchange);
>
> If I understand this right then this method calls the close(Message)
> method on the conduit. So this is where I should remove the correlation?
> For this to work I have to encode the correlationId in the Message or
> the Exchange. Any idea where I should put it? Should I create a new map
> key for this or is there a default place for correlationIds?
There isn't a place for it. If this is JMS only, you can just use any key
you want. Define a string in JMSConduit like:
JMSConduit.class.getName() + ".correlationId"
or similar and set that on the message/exchange and retrieve it later.
> > Not sure if that's completely possible. Things like HTTP and CORBA
> > don't have any correlation ID on the wire. Thus, those transports would
> > need to add stuff and record various "fake" id's and such to make that
> > work. Basically, you remove it from JMS, but add it to the others. (I
> > think)
>
> HTTP may not need a correlationId in its normal snychronous way. But
> there are use cases where two separate http connections are used for
> request and reply.
> I think microsoft calls this duplex mode in wcf. In this case HTTP would
> work like JMS. I am not sure if this modeis relevant in java but it
> could be used in one of the ws* specs.
This is done via ws-addressing which puts the correlation information into the
ws-addressing headers and such and the ws-addressing interceptors handle
those correlation things.
> >> Another thing are the Executors and Workqueues. The current spring
> >> versions already provide this functionality. Do you think it is possible
> >> to switch to
> >> the spring implementations and remove this code from cxf?
> >
> > Nope. CXF needs to work for the "normal" usecases (JAX-WS/SOAP/HTTP)
> > without spring. That said, we could augment it to allow the spring
> > things to be used instead if available/configured.
>
> Hmm I understand that it is not always necessary to use a spring
> context. But wouldn´t it be better to let a more generic framework like
> spring solve things like Executors and Workqueues?
Sure, as long as it doesn't HAVE to always use those things. :-)
--
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Re: JMS transport sync/async......
Posted by Christian Schneider <ch...@die-schneider.net>.
Daniel Kulp schrieb:
>> Btw. is it really necessary to do different things for sync and async?
>> Of course the ClientImpl has to support a sync and async mode but I think
>> the transports could be made completely async. Does the Exchange even
>> has to know if it is synchronous?
>>
>
> It could, but HTTP and CORBA performance would certainly suffer and the number
> of threads blocked on requests in the sync cases would double. Since part
> of what I'm trying to do is eliminate/reduce the number of blocked threads,
> that would be bad. Basically, if a request is known to be synchronous, if
> the transports can do everything on the single thread, that's greatly
> preferred. Otherwise, you have the ClientImpl blocking as well as a
> background thread blocking for the transport. (along with all the context
> switches and such to flip threads through the CPU)
>
>
I don´t think that this has to be the case. An async http request could
send the request and store the http session in the message.
Then it could return. The client would then call another function to
wait for the response. I am not yet sure how this could work but I will
try to work out something that works equally well with http and jms.
> I think the client calls into the Conduit with a "done" message or something
> at the end. The JMS conduit should be able to do any cleanup there:
> getConduitSelector().complete(exchange);
>
If I understand this right then this method calls the close(Message)
method on the conduit. So this is where I should remove the correlation?
For this to work I have to encode the correlationId in the Message or
the Exchange. Any idea where I should put it? Should I create a new map
key for this or is there a default place for correlationIds?
>
>> Generally I would
>> suggest doing the whole correlation already in the client. So we could
>> keep this out of the transport code.
>>
>
> Not sure if that's completely possible. Things like HTTP and CORBA don't
> have any correlation ID on the wire. Thus, those transports would need to
> add stuff and record various "fake" id's and such to make that work.
> Basically, you remove it from JMS, but add it to the others. (I think)
>
HTTP may not need a correlationId in its normal snychronous way. But
there are use cases where two separate http connections are used for
request and reply.
I think microsoft calls this duplex mode in wcf. In this case HTTP would
work like JMS. I am not sure if this modeis relevant in java but it
could be used in one of the ws* specs.
>
>> Another thing are the Executors and Workqueues. The current spring
>> versions already provide this functionality. Do you think it is possible
>> to switch to
>> the spring implementations and remove this code from cxf?
>>
>
> Nope. CXF needs to work for the "normal" usecases (JAX-WS/SOAP/HTTP) without
> spring. That said, we could augment it to allow the spring things to be
> used instead if available/configured.
>
Hmm I understand that it is not always necessary to use a spring
context. But wouldn´t it be better to let a more generic framework like
spring solve things like Executors and Workqueues?
Greetings
Christian
--
Christian Schneider
---
http://www.liquid-reality.de
Re: JMS transport sync/async......
Posted by Daniel Kulp <dk...@apache.org>.
On Sunday 26 October 2008 9:01:44 am Christian Schneider wrote:
> Hi Dan,
>
> I have looked into ClientImpl and JMSConduit. I think the code you added
> should work.
> The JMSConduit.onMessage is called from DefaultMessageListenerContainer
> which uses a spring TaskExecutor. Additionally it can be configured
> to use several threads to listen on jms messages. So I think there is no
> need for a workqueue.
Ok. Cool. That's what I wanted to know.
> Additionally ClientImpl uses another executor.
Not normally, only if the user configures an executor into the client which
isn't exactly a normal occurrance. However, it does provide a mechanism to
the user to workaround any issues.
> Btw. is it really necessary to do different things for sync and async?
> Of course the ClientImpl has to support a sync and async mode but I think
> the transports could be made completely async. Does the Exchange even
> has to know if it is synchronous?
It could, but HTTP and CORBA performance would certainly suffer and the number
of threads blocked on requests in the sync cases would double. Since part
of what I'm trying to do is eliminate/reduce the number of blocked threads,
that would be bad. Basically, if a request is known to be synchronous, if
the transports can do everything on the single thread, that's greatly
preferred. Otherwise, you have the ClientImpl blocking as well as a
background thread blocking for the transport. (along with all the context
switches and such to flip threads through the CPU)
> About your question regarding the wait. I would like to remove the wait
> and also the config option receiveTimeout. If the Client can do this
> then that is the better solution.
> There is one thing we have to keep in mind though. The sendExchange
> method adds an entry to the correlationMap. This has to be removed after
> the timeout. Normally this is done after the wait.
> I guess there is no easy solution for this problem.
I think the client calls into the Conduit with a "done" message or something
at the end. The JMS conduit should be able to do any cleanup there:
getConduitSelector().complete(exchange);
>Generally I would
> suggest doing the whole correlation already in the client. So we could
> keep this out of the transport code.
Not sure if that's completely possible. Things like HTTP and CORBA don't
have any correlation ID on the wire. Thus, those transports would need to
add stuff and record various "fake" id's and such to make that work.
Basically, you remove it from JMS, but add it to the others. (I think)
> Another thing are the Executors and Workqueues. The current spring
> versions already provide this functionality. Do you think it is possible
> to switch to
> the spring implementations and remove this code from cxf?
Nope. CXF needs to work for the "normal" usecases (JAX-WS/SOAP/HTTP) without
spring. That said, we could augment it to allow the spring things to be
used instead if available/configured.
Dan
> Greetings
>
> Christian
>
> Daniel Kulp schrieb:
> > Christian,
> >
> > When you get some time, can you look at what I've done in the JMS
> > transport to make sure it's all OK and doesn't introduce some massive
> > scalability issue?
> >
> > Basically, I now call the message observer directly from the
> > onMessage(JMSMessage) call. This means its called on the thread that
> > the JMS queue provides instead of from the CXF calling thread. Right
> > now, if it's a synchronous invoke, I left the "wait()" in place on the
> > main thread, but that's really not needed. It could return immediately
> > as the ClientImpl will then wait if it's supposed to be synchronous. I
> > mostly left it there due to the jmsTemplate.getReceiveTimeout() thing.
> > If we return, the timeout would need to be configured on the client
> > itself, which might not be a bad thing. Not really sure. Maybe the
> > default could be RECEIVE_TIMEOUT_NO_WAIT and only wait on that main
> > thread if it's set otherwise? I don't really know, not my area of
> > expertise.
> >
> > I guess my main concern is if it's OK to process the response on the JMS
> > provided thread. Is that part of a thread pool or similar? If not,
> > we'll need to throw it on a workqueue. That's easy enough to do, but I
> > wanted to hear from you first.
> >
> > Thanks!
--
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Re: JMS transport sync/async......
Posted by Christian Schneider <ch...@die-schneider.net>.
Hi Dan,
I have looked into ClientImpl and JMSConduit. I think the code you added
should work.
The JMSConduit.onMessage is called from DefaultMessageListenerContainer
which uses a spring TaskExecutor. Additionally it can be configured
to use several threads to listen on jms messages. So I think there is no
need for a workqueue.
Additionally ClientImpl uses another executor.
Btw. is it really necessary to do different things for sync and async?
Of course the ClientImpl has to support a sync and async mode but I think
the transports could be made completely async. Does the Exchange even
has to know if it is synchronous?
About your question regarding the wait. I would like to remove the wait
and also the config option receiveTimeout. If the Client can do this
then that is the better solution.
There is one thing we have to keep in mind though. The sendExchange
method adds an entry to the correlationMap. This has to be removed after
the timeout. Normally this is done after the wait.
I guess there is no easy solution for this problem. Generally I would
suggest doing the whole correlation already in the client. So we could
keep this out of the transport code.
Another thing are the Executors and Workqueues. The current spring
versions already provide this functionality. Do you think it is possible
to switch to
the spring implementations and remove this code from cxf?
Greetings
Christian
Daniel Kulp schrieb:
> Christian,
>
> When you get some time, can you look at what I've done in the JMS transport to
> make sure it's all OK and doesn't introduce some massive scalability issue?
>
> Basically, I now call the message observer directly from the
> onMessage(JMSMessage) call. This means its called on the thread that the
> JMS queue provides instead of from the CXF calling thread. Right now, if
> it's a synchronous invoke, I left the "wait()" in place on the main thread,
> but that's really not needed. It could return immediately as the
> ClientImpl will then wait if it's supposed to be synchronous. I mostly left
> it there due to the jmsTemplate.getReceiveTimeout() thing. If we return,
> the timeout would need to be configured on the client itself, which might
> not be a bad thing. Not really sure. Maybe the default could be
> RECEIVE_TIMEOUT_NO_WAIT and only wait on that main thread if it's set
> otherwise? I don't really know, not my area of expertise.
>
> I guess my main concern is if it's OK to process the response on the JMS
> provided thread. Is that part of a thread pool or similar? If not, we'll
> need to throw it on a workqueue. That's easy enough to do, but I wanted to
> hear from you first.
>
> Thanks!
>
--
Christian Schneider
---
http://www.liquid-reality.de