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:
@ -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) {
|
if (request.getParameter("i2p.contextId") != null) {
|
||||||
session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
|
session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
|
||||||
}%>
|
}%>
|
||||||
|
@ -206,6 +206,8 @@
|
|||||||
<copy file="history.txt" todir="pkg-temp/" />
|
<copy file="history.txt" todir="pkg-temp/" />
|
||||||
<mkdir dir="pkg-temp/docs" />
|
<mkdir dir="pkg-temp/docs" />
|
||||||
<copy file="readme.html" todir="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>
|
||||||
<target name="tarball" depends="preppkg">
|
<target name="tarball" depends="preppkg">
|
||||||
<tar compression="bzip2" destfile="i2p.tar.bz2">
|
<tar compression="bzip2" destfile="i2p.tar.bz2">
|
||||||
|
12
history.txt
12
history.txt
@ -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
|
2004-09-04 jrandom
|
||||||
* Update the SDK to automatically reconnect indefinitely with an
|
* Update the SDK to automatically reconnect indefinitely with an
|
||||||
|
@ -100,7 +100,7 @@ wrapper.jvm_exit.timeout=60
|
|||||||
wrapper.jvm_exit.timeout=30
|
wrapper.jvm_exit.timeout=30
|
||||||
|
|
||||||
# give the OS 30s to clear all the old sockets / etc before restarting
|
# 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
|
# use the wrapper's internal timer thread. otherwise this would
|
||||||
# force a restart of the router during daylight savings time as well
|
# force a restart of the router during daylight savings time as well
|
||||||
|
@ -82,6 +82,14 @@ public class Router {
|
|||||||
public Router(Properties envProps) { this(null, envProps); }
|
public Router(Properties envProps) { this(null, envProps); }
|
||||||
public Router(String configFilename) { this(configFilename, null); }
|
public Router(String configFilename) { this(configFilename, null); }
|
||||||
public Router(String configFilename, Properties envProps) {
|
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();
|
_config = new Properties();
|
||||||
_context = new RouterContext(this, envProps);
|
_context = new RouterContext(this, envProps);
|
||||||
if (configFilename == null)
|
if (configFilename == null)
|
||||||
@ -554,6 +562,8 @@ public class Router {
|
|||||||
dumpStats();
|
dumpStats();
|
||||||
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete", new Exception("Shutdown"));
|
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete", new Exception("Shutdown"));
|
||||||
try { _context.logManager().shutdown(); } catch (Throwable t) { }
|
try { _context.logManager().shutdown(); } catch (Throwable t) { }
|
||||||
|
File f = new File(getPingFile());
|
||||||
|
f.delete();
|
||||||
if (_killVMOnEnd) {
|
if (_killVMOnEnd) {
|
||||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||||
Runtime.getRuntime().halt(exitCode);
|
Runtime.getRuntime().halt(exitCode);
|
||||||
@ -685,6 +695,77 @@ public class Router {
|
|||||||
r.runRouter();
|
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 static int __id = 0;
|
||||||
private class ShutdownHook extends Thread {
|
private class ShutdownHook extends Thread {
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
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 String VERSION = "0.4";
|
||||||
public final static long BUILD = 4;
|
public final static long BUILD = 5;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION);
|
System.out.println("I2P Router version: " + VERSION);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
Reference in New Issue
Block a user