>HI,
> Right now, our servers are in prod, and we cannot have down
time.we
>update our application every week and are looking to do it fast and without
>any error. So we use the share memory file of mod_serv to place out jservin
>graceful mode, but what is the best moment to kill our jserv to be sure
that
>no session are still active? We find nothing, so i had the possibility to
>terminate JServ in Graceful Mode with the signal -g just like the -s signal
>to terminate now!
>
> All is working fine. I write a little document with all the
>modification to implement the graceful stop.
>
> What are you thinking of this?
>
>
>I'm thinking I'd love to see your writeup - I need a solution to this
>problem - I can't seem to use the shutdown stuff with jserv the
>way it currently is in a load balancing config (1.0) :(
>
>How are you removing it from the shm file?
>
First, we use a script to put a '\' in the shm, after we send a
signal to JServ (like the one to restart or to stop) to place him
in graceful stop. I write a procedure to modify JServ. I not sure
its the complete solution, i may have forgot something... Tell me
if something wrong append.
Thanks
-------------------------------------------------------------------
How to change Jserv to accept Graceful Stop.
First, we need to add a signal to notify Jserv to stop.
In JServ.java add the following case in the switch of the main method:
case 'g': if (confFile == null) usage();
signal("graceful"); break;
In JServ.java change the "if block" in the signal method:
private static synchronized void signal(String signal) {
Configurations confs = null;
AuthenticatedSocket socket = null;
byte[] signalBytes = new byte[2];
signalBytes[0] = (byte) 254;
if (signal.equals("restart")) {
signalBytes[1] = (byte) 1;
} else if (signal.equals("terminate")){
signalBytes[1] = (byte) 15;
} else {
signalBytes[1] = (byte) 255;
}
In In JServConnection.java we need to catch the signal, so at the end of
the 254 case insert:
if (signal == 1) { // SIGHUP
JServ.restart();
} else if (signal == 15) { // SIGTERM
JServ.terminate();
} else if (signal == 255) { // SIGGRACEFUL
JServ.terminateGracefully();
}
Now that we catch the signal, we must tell all the servlet manager to change
their
State. To do that we must add state value, add the following member in
JservServletManager.java
/**
* All possible state for servlet manager.
*/
public static final int RUNNING = 0;
public static final int GRACEFULSTOPREQUEST = 1;
public static final int STOPPED = 2;
/**
* Current state of the Servlet Manager.
*/
private int currentState = RUNNING;
Add get/set to change state in JservServletManager.java.
/**
* To set the state of the Servlet Manager.
* @PARAM state Can be: RUNNING, GRACEFULSTOPREQUEST or STOPPED.
*/
public synchronized void setState(int state)
{
currentState = state;
}
/**
* Return the state of the Servlet Manager.
*
* @RETURN RUNNING, GRACEFULSTOPREQUEST or STOPPED.
*/
public synchronized int getState()
{
return currentState;
}
Now we must add the method that will handle the graceful stop. So add the
following in Jserv.java
/**
* Set all the ServletManager in Graceful Stop State. If all the manager
* are already stopped, the application will be terminated.
*/
protected static synchronized void terminateGracefully() {
// Set to true when we can terminate right now, false otherwise
boolean canStop=true;
// Change and check all the Servlet manager state.
Enumeration enum = servletManagerTable.elements();
while (enum.hasMoreElements()) {
JServServletManager manager =
(JServServletManager) enum.nextElement();
// If the manager is not stopped, then set canStop=false. This
// prevent to terminate too early.
if (manager.getState() == JServServletManager.RUNNING) {
manager.setState(JServServletManager.GRACEFULSTOPREQUEST);
canStop = false;
}
else if (manager.getState() != JServServletManager.STOPPED) {
canStop = false;
}
}
// If all manager are stopped then terminate
if (canStop==true)
terminate();
}
To terminate, a Servlet manager must have an empty Session table, the best
way to validate this, is to use the House Keeping thread, modify the run()
method in JservServletManager.java, the modification to do are in bold.
public void run() {
Enumeration sesses;
JServSession sess;
long sysMillis;
while(true) {
// sleep for 5 seconds.
try {
Thread.sleep(sessionCheckFrequency);
} catch(InterruptedException exc) { }
// walk through all sessions and invalidate old ones
sesses = sessions.elements();
sysMillis = System.currentTimeMillis();
//------From here---(Graceful
stop)-------------------------------------------------
// if we dont have elements and we are in graceful stop then
// terminate
if (!sesses.hasMoreElements() &&
getState()==GRACEFULSTOPREQUEST) {
// Change our state to STOPPED
setState(STOPPED);
// Tell JServ to try a graceful stop
JServ.terminateGracefully();
}
else {
if (JServ.log.active && sesses.hasMoreElements() &&
getState()==GRACEFULSTOPREQUEST) {
JServ.log.log(CH_INFO, "Waiting for remaining
sessions");
}
}
//------To here---(Graceful
stop)-------------------------------------------------
while(sesses.hasMoreElements()) {
sess = (JServSession) sesses.nextElement();
synchronized (sess) {
try {
if ((sysMillis - sess.lastAccessTime >
sessionTimeout) ||
((sess.isNew()) &&
(sysMillis - sess.lastAccessTime >
newSessionTimeout))) {
sess.invalidate();
}
}
catch (IllegalStateException ignored) {}
}
}
}
}
--
----------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Archives and Other: <http://java.apache.org/main/mail.html>
Problems?: [EMAIL PROTECTED]