Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Listeners in a cluster

 
Luc Russell
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have a web application with a ServletContextListener which starts a timer in the contextInitialised method in order to run a scheduled batch process. This works fine in a single server situation, but when the application is deployed in a cluster, the listener is instantiated once for each server, so the process is run more than once. I'd be most grateful if anyone has any suggestions on how to handle this - so far the only thing I can think of is to add a flag into the session when the timer is created, so it only happens once (am I right in believing the HTTPSession applies across all the instances in a cluster?).
Thanks
Luc
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34681
367
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Luc,
The HttpSession is shared across instances (it is really serialized, but it acts as one.) The problem is that there is one HttpSession per user. Do you want one batch job per user or one batch job in general?
You could use an external file as a flag if the cluster is one box. Also, you could deploy the timer for the batch job as a separate web app and only deploy it to one machine in the cluster.
 
Luc Russell
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks very much for these comments; in the end, getting access to the session was going to be a bit of a problem from the listener class itself, so instead I used the JNDI context to hold a 'lock' flag (not something I'd tried before). In the EJB method which is called by the listener, I use something like this to check for the presence of a lock, and only start the process if one is not registered:
try {
ctx = new InitialContext();
if(ctx.lookup(TRIGGER)!=null){
Boolean b = (Boolean)ctx.lookup(TRIGGER);
triggered=b.booleanValue();
}
} catch (NamingException e) {
log.info("Process has not yet been started, starting now");
}
if(!triggered)
ctx.bind(TRIGGER,new Boolean(true));
Then at the end of the method, the lock is cleared. When multiple timers exist and fire notifications at the same time, the process will not trigger, if a lock is registered. This seems to do the job, but please let me know if you see any problems with this approach!
Thanks
Luc
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic