camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Strachan" <>
Subject Re: Stopping some routes and ServiceSupport question.
Date Tue, 20 Nov 2007 11:28:34 GMT
On 19/11/2007, Roman Kalukiewicz <> wrote:
> Hello!
> My problem is that I would like to have a way to stop some endpoints
> so they don't receive messages.
> My problem is that before redeploying some http service I would like
> to wait some time so every message that is processed at the moment is
> finished. Of course at that time I cannot consume any new message from
> the endpoint.
> If everything is executed in transaction that can be rolled back, then
> there is no problem, but my flow contains http endpoint that cannot be
> rolled back, so I shouldn't rollback my original message if it hit the
> http endpoint.
> Best way for me is to stop jms consumer endpoint (that is at the very
> begining of the flow), wait until all exchanges are processed, and
> then shut down the context.

Great point. We really need a graceful shutdown of the routes; where
we first stop the consumers from receiving any more new messages,
while completing any pending message flows.

I've just made a minor patch to EventDrivenConsumerRoute to ensure the
consumer is added first; so its stopped first which should help.

> I've seen that those consumers are not exposed by JMX - only routes
> are and they can be stopped. But the problem is that ServiceSupport
> doesn't allow me to start a service that was previously stopped,
> because when I do that, this service has started==true and
> stopped=true and it cannot be used then (I've already implemented this
> stop() and start() methods of ManagedRoute to stop/start all
> route.getServicesForRoute() services).
> My question is if ServiceSupport should allow me to start->stop->start
> or it is forbidden by default and there is important reason it is done
> this way?

FWIW I've always been very nervous of having stop() then start()
behaviour on POJOs; as its soooo easy to mess up and introduce bugs
(and folks never get around to writing test cases where you start and
stop then start and test things) and there's always some bit of state
that gets in a mess etc. e.g. I remember how amazingly complex many of
the GBeans were in Geronimo; just because they insisted that all POJOs
have to deal with stopping then starting again. Its so much simpler to
just trash the POJO and make a new one :)

Once a RouteType is stopped; I'd be tempted to re-activate it again
and start a whole new set of service objects which once stopped are
discarded. Then things stay really simple and we don't have a ton of
bugs caused by restarting things.

> The second question is if I should solve my problem this way? Maybe
> there are different ideas about such problems?

So we definitely need to put in place a graceful shutdown mechanism;
and a mechanism to restart a route (say if its been modified, or if
you just wanted to pause a particular route for a while then
reactivate it again).

For graceful shutdown, I guess the consumers need to do graceful
shutdown (the EventDrivenConsumer and PollingConsumer); so long as
they are stopped first before any other related services for a
RouteType, and the consumers complete processing the current message
exchange correctly before actually stopping then things should work I
think. We will need lots of tests to check this really does work
though! :)

To handle restarting of the routes, I guess we just need to refactor
the RouteType activation code of routes; so they can be more easily
started and stopped. To get the code to the state we need there's
probably a fair bit of work required; e.g. we'd probably wanna keep
track of all the Service objects related to each RouteType so that we
can just stop a single RouteType; then restart it again. Right now we
tend to add all services for a RouteType to the CamelContext (so its
gonna be hard to figure out how to stop just a single RouteType).

To activate a route we currently use the addRoutes() method on
RouteType; I guess we need to add better start/stop methods to the
RouteType and clean that code up a bit. (It could use some refactoring
to tidy it up :).  The RouteContext; we could rename to something a
bit more useful maybe - but maybe this object could be used to store
the various objects and services required. Then the RouteContext could
be stopped and discarded and a new one created etc.

i.e. the RouteType object could stick around and be capable of being
start()'ed, then stop()'d then start()'ed again - but on the start()
it basically makes a whole new RouteContext object which has its own
Processor, Consumer objects etc. i.e. just have one restartable object
- the RouteType - which we can test heavily that it really can restart
nicely - meanwhile all other objects involved (the various Processor,
Service and Consumer implementations) are all discarded after they are

BTW I'm not a fan of the class name RouteType either :) I was having a
bad-class-naming-day, apologies! We already had Route so wanted some
kinda prefix to add to the types in the camel.model package to avoid
clashes. I guess "Definition" maybe a better postfix. RouteDefinition
for example? The basic idea is that RouteType is the logical model of
the route which can then be activated (into various Services,
Consumers, Processors and so forth) - then it can be stopped, the
objects discarded and a whole new set of objects created again later.

We should also support things like stopping a RouteType, editing the
definition of the routing rules - then restarting too.

We've got the MBeans now to be able to do this from JMX for example -
see the ManagedRoute. I can imagine us wishing to grab a RouteType
from a running process through some UI and edit the EIP model, then
restart just a single RouteType which would be rather cool.

Sorry for the long ramble - but yes I totally agree, we need to
improve the code to allow graceful stop and restarting of individual

Open Source Integration

View raw message