Probably a solution could be using the same lock object both in the
continuation as in the synchronized blocks:
@@ -334,9 +334,9 @@
to = ((HttpComponent)
getServiceUnit().getComponent()).getConfiguration().getConsumerProcessorSuspendTime();
}
- final Continuation continuation =
ContinuationSupport.getContinuation(request, null);
+ final Object mutex = getOrCreateMutex(exchange);
+ final Continuation continuation =
ContinuationSupport.getContinuation(request, mutex);
exchange = (MessageExchange) continuation.getObject();
- final Object mutex = getOrCreateMutex(exchange);
// Synchronize on the mutex object while we're tinkering
with the continuation object
synchronized (mutex) {
Please tell me what you think about that.
Thanks,
Hernán.
On Fri, Feb 3, 2012 at 2:57 PM, Hernan Sigliani
<[email protected]> wrote:
> Hi,
> I'm currently working on the testing of the compatibility of our
> services developed for smx 3.3.2 on the new 3.4.0 platform, since we
> are thinking upgrade to that version.
> I found an issue in the http:consumer component (2011.02) that makes
> all http requests get a timeout exception. That is not happening in
> previous versions such as 2009.1.
> The endpoint's declaration looks like this:
>
> <http:consumer service="b:http"
> endpoint="endpoint"
> targetService="b:xslt"
> locationURI="http://0.0.0.0:8192/bridge/"
> defaultMep="http://www.w3.org/2004/08/wsdl/in-out" />
>
> I think the problem is in this piece of code extracted from
> org.apache.servicemix.http.endpoints.HttpConsumerEndpoint:
>
> 322: public void process(HttpServletRequest request,
> HttpServletResponse response) throws Exception {
> ...
> 339: final Object mutex = getOrCreateMutex(exchange);
> 340:
> 341: // Synchronize on the mutex object while we're tinkering
> with the continuation object
> 342: synchronized (mutex) {
> 343: if (isNewContinuation(continuation)) {
> ...
> 361: // Send the exchange and then suspend the HTTP
> request until the message exchange gets answered
> 362: send(exchange);
> ...
> 372: boolean istimeout = !continuation.suspend(to);
> 373:
> 374: // Continuation is being ended (either because the
> message exchange was handled or the continuation timed out)
> 375: // Cleaning up the stored objects for this continuation
> now
> 376: exchange = doEndContinuation(continuation);
> 377:
> 378: // Throw exception when HTTP time-out has occurred
> 379: if (istimeout) {
> 380: throw new HttpTimeoutException(exchange);
> 381: }
> 382: }
>
> Here the continuation is suspended inside the synchorized block using
> the exchange as lock object. By the other side, the release() is sent
> to the continuation in the following method which processes the
> exchange's result:
>
> 282: public void process(MessageExchange exchange) throws Exception {
> 283: final String id = exchange.getExchangeId();
> 283: final Object mutex = mutexes.get(id);
> ...
> 293: synchronized (mutex) {
> 294: final Continuation continuation = continuations.get(id);
> ...
> 301: continuation.resume();
> ...
> 313: }
>
> The resume() method is called inside another synchrozed block using
> the same object as lock, so the sequence is:
> - lock over mutex starts
> - continuation is suspended until its timeout
> - lock over mutex ends
> - the code inside the method which processes the exchange's result
> gets control.
> I think the point is that it always gets control after timeout occurs.
> I made the tests on smx 3.3.2, http component 2009.01 (it works) and
> on smx 3.4.0, http
> component 2011.02 (timeout issue). In both cases I used the managed
> servlet of the web distribution running on tomcat. The standalone
> distribution using jetty connector work fine.
>
> Thanks in advance,
> Hernan