I work on a fairly complex Java server app running in a Tomcat (as a War).
Our existing pattern:
When we start up we register various classes that control their own threads, some have external or internal communications (We use Hazelcast, JMS, and a few database systems). We send each of these classes an init() signal when they are registered so they can start doing their work.
On shutdown we send a destroy() signal to each (in reverse order) to ask them to stop their threads.
The problem is that this is quite fragile. If the destroy() method has to shut down hazelcast but something else is still sending message hazelcast tends to hang on shutdown. Now the destroythread is hung and doesn't get to everything else.
In some cases I tried to code destroy like this:
destroy() {
shuttingDown=true;
hazelcast.disconnect();
//maybe call destroy on child threads here...
// in some cases send interrupt signals to threads that might be waiting on data...
}
This way a loop can be dependent partially on !shuttingDown.
This fixed some problems but it's not universal.
I was wondering if anyone has used a good, reliable pattern that we could apply to each subsystem that will let us shut everything down.
I've considered a global shuttingDown (or "running") Atomic flag to reference from all loops but that certainly seems a bit hacky. Passing a shuttingDown Atomic might work (but at some point if it's going to be passed everywhere, isn't it essentially a global/singleton?)
Another approach is adding states, currently we have init() & destroy(). We could have init(), start(), stop() and destroy(). The stop could stop loops before we try to kill the services.
Whatever approach we take will be a pretty big refactor, so I thought I'd ask if there was a good known working pattern.
Aucun commentaire:
Enregistrer un commentaire