On 19/11/2007, Roman Kalukiewicz <[EMAIL PROTECTED]> 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 stopped. 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 RouteTypes. -- James ------- http://macstrac.blogspot.com/ Open Source Integration http://open.iona.com
