shashank created CAMEL-26643:
--------------------------------

             Summary: camel-sjms - a consumer stopped and started again with 
asyncStopListener=true ends up started without a running listener container
                 Key: CAMEL-26643
                 URL: https://issues.apache.org/jira/browse/CAMEL-26643
             Project: Camel
          Issue Type: Bug
          Components: camel-sjms
            Reporter: shashank
            Assignee: shashank


Found while checking other components for the shape of CAMEL-26536 (camel-jms): 
an asynchronous stop task of a consumer that outlives a start of the same 
consumer. Reproduced on the real classes, with the tasks the consumer submits 
to the component's async start/stop pool held and run in a chosen order 
(embedded Artemis).

{{SjmsConsumer}} keeps one listener container for every run of the consumer. 
With {{asyncStopListener=true}}, {{doStop}} submits a task that later calls 
{{stopAndShutdownService(listenerContainer)}}. If the same consumer is started 
again before that task runs (route policies that stop and start the consumer, 
such as {{MasterRoutePolicy}} or {{HazelcastRoutePolicy}}, the stop/start 
operations of the managed consumer in JMX, or code that calls {{stop()}} / 
{{start()}} on it), {{doStart}} finds the container still started 
({{startService}} is a no-op), and the task then stops and shuts it down. The 
consumer reports Started and receives nothing, with no error logged, until it 
is restarted again. The same happens if the start runs between the {{stop()}} 
and the {{shutdown()}} of a task that is already running.

Short trace:
{noformat}
1 lifecycle : consumer.stop()  -> doStop submits stop task S                    
    (SjmsConsumer doStop)
2 lifecycle : consumer.start() -> doStart: prepareAndStartListenerContainer()
                                  startService(container) -> no-op, container 
still Started
3 S         : stopAndShutdownService(container) -> container stopped and shut 
down
  -> consumer Started, listener container Shutdown: no message is received
{noformat}

With {{asyncStartListener=true}} the start task has the opposite problem: a 
start task that runs after the consumer was stopped (it was pending, or the 
consumer was stopped while the task was starting the container) starts the 
listener container of a stopped consumer, which then keeps receiving and 
routing messages. Under a master/slave route policy, two nodes consume.

A route restart ({{restartRoute}}, {{stopRoute}} + {{startRoute}}) is not 
affected: the route creates a new consumer, which has a listener container of 
its own. camel-sjms2 uses the same consumer and is affected the same way.

Expected: a consumer that is started has a running listener container, and a 
consumer that is stopped has none, whatever the order in which the asynchronous 
tasks run.

Suggested fix: the asynchronous tasks check the state of the consumer under a 
lock of their own that serializes the start and the stop of the listener 
container. The stop task stops and shuts down the container only if the 
consumer is still stopped; the start task starts it only if the consumer still 
runs, and stops it again if the consumer was stopped while it was starting. A 
synchronous start waits for a stop task that is stopping the container. The 
stop, shutdown and suspend of the consumer (and so a route stop) do not wait 
for the stop task, so {{asyncStopListener}} keeps its purpose.

Affected: main; the asynchronous stop and start tasks are the same in 4.18.x 
and 4.14.x.

_Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to