2004-09-04 jrandom

* Added some basic guards to prevent multiple instances from running.
       Specifically, a file "router.ping" in the install directory which is
       written to once a minute - if that file exists and has been modified
       within the last minute, refuse to start up.  In turn, adjust the
       service wrapper to wait a minute before restarting a crashed JVM.
     * Create a "work" directory in the I2P install dir which Jetty will
       use for all of its temporary files.
     * Tell the browser not to cache most of the router console's pages.
This commit is contained in:
jrandom
2004-09-04 21:54:08 +00:00
committed by zzz
parent f72aa7884d
commit db339d40de
6 changed files with 104 additions and 5 deletions

View File

@ -1,4 +1,10 @@
<%
<% response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
// the above will b0rk if the servlet engine has already flushed
// the response prior to including nav.jsp, so nav should be
// near the top
if (request.getParameter("i2p.contextId") != null) {
session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
}%>

View File

@ -206,6 +206,8 @@
<copy file="history.txt" todir="pkg-temp/" />
<mkdir dir="pkg-temp/docs" />
<copy file="readme.html" todir="pkg-temp/docs/" />
<mkdir dir="pkg-temp/work" />
<touch file="pkg-temp/work/ignore.this" />
</target>
<target name="tarball" depends="preppkg">
<tar compression="bzip2" destfile="i2p.tar.bz2">

View File

@ -1,4 +1,14 @@
$Id: history.txt,v 1.5 2004/09/03 14:46:08 jrandom Exp $
$Id: history.txt,v 1.6 2004/09/04 00:41:42 jrandom Exp $
2004-09-04 jrandom
* Added some basic guards to prevent multiple instances from running.
Specifically, a file "router.ping" in the install directory which is
written to once a minute - if that file exists and has been modified
within the last minute, refuse to start up. In turn, adjust the
service wrapper to wait a minute before restarting a crashed JVM.
* Create a "work" directory in the I2P install dir which Jetty will
use for all of its temporary files.
* Tell the browser not to cache most of the router console's pages.
2004-09-04 jrandom
* Update the SDK to automatically reconnect indefinitely with an

View File

@ -100,7 +100,7 @@ wrapper.jvm_exit.timeout=60
wrapper.jvm_exit.timeout=30
# give the OS 30s to clear all the old sockets / etc before restarting
#wrapper.restart.delay=30
wrapper.restart.delay=60
# use the wrapper's internal timer thread. otherwise this would
# force a restart of the router during daylight savings time as well

View File

@ -82,6 +82,14 @@ public class Router {
public Router(Properties envProps) { this(null, envProps); }
public Router(String configFilename) { this(configFilename, null); }
public Router(String configFilename, Properties envProps) {
if (!beginMarkingLiveliness(envProps)) {
System.err.println("ERROR: There appears to be another router already running!");
System.err.println(" Please make sure to shut down old instances before starting up");
System.err.println(" a new one. If you are positive that no other instance is running,");
System.err.println(" please delete the file " + getPingFile(envProps));
System.exit(-1);
}
_config = new Properties();
_context = new RouterContext(this, envProps);
if (configFilename == null)
@ -554,6 +562,8 @@ public class Router {
dumpStats();
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete", new Exception("Shutdown"));
try { _context.logManager().shutdown(); } catch (Throwable t) { }
File f = new File(getPingFile());
f.delete();
if (_killVMOnEnd) {
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
Runtime.getRuntime().halt(exitCode);
@ -685,6 +695,77 @@ public class Router {
r.runRouter();
}
private static String getPingFile(Properties envProps) {
if (envProps != null)
return envProps.getProperty("router.pingFile", "router.ping");
else
return "router.ping";
}
private String getPingFile() {
return _context.getProperty("router.pingFile", "router.ping");
}
private static final long LIVELINESS_DELAY = 60*1000;
/**
* Start a thread that will periodically update the file "router.ping", but if
* that file already exists and was recently written to, return false as there is
* another instance running
*
* @return true if the router is the only one running
*/
private boolean beginMarkingLiveliness(Properties envProps) {
String filename = getPingFile(envProps);
File f = new File(filename);
if (f.exists()) {
long lastWritten = f.lastModified();
if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) {
System.err.println("WARN: Old router was not shut down gracefully, deleting router.ping");
f.delete();
} else {
return false;
}
}
// not an I2PThread for context creation issues
Thread t = new Thread(new MarkLiveliness(f));
t.setName("Mark router liveliness");
t.setDaemon(true);
t.start();
return true;
}
private class MarkLiveliness implements Runnable {
private File _pingFile;
public MarkLiveliness(File f) {
_pingFile = f;
}
public void run() {
_pingFile.deleteOnExit();
do {
ping();
try { Thread.sleep(LIVELINESS_DELAY); } catch (InterruptedException ie) {}
} while (_isAlive);
_pingFile.delete();
}
private void ping() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(_pingFile);
fos.write(("" + System.currentTimeMillis()).getBytes());
} catch (IOException ioe) {
if (_log != null) {
_log.log(Log.CRIT, "Error writing to ping file", ioe);
} else {
System.err.println("Error writing to ping file");
ioe.printStackTrace();
}
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
}
}
private static int __id = 0;
private class ShutdownHook extends Thread {

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.21 $ $Date: 2004/09/03 14:46:07 $";
public final static String ID = "$Revision: 1.22 $ $Date: 2004/09/04 00:41:42 $";
public final static String VERSION = "0.4";
public final static long BUILD = 4;
public final static long BUILD = 5;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID);