i2psnark:

- Don't create SnarkManager instance until first call,
      so it doesn't create the i2psnark dir, read the config,
      etc., for single Snark instances.
    - Don't read i2psnark.config twice; fix setting
      i2psnark.dir
    - More Snark constructor changes for calling from router
    - Make max connections per torrent configurable
This commit is contained in:
zzz
2008-11-18 02:18:23 +00:00
parent 134764b154
commit 0ff8167425
5 changed files with 71 additions and 21 deletions

View File

@ -47,12 +47,14 @@ public class I2PSnarkUtil {
private Set _shitlist;
private int _maxUploaders;
private int _maxUpBW;
private int _maxConnections;
public static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers";
public static final boolean DEFAULT_USE_OPENTRACKERS = true;
public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers";
public static final String DEFAULT_OPENTRACKERS = "http://tracker.welterde.i2p/a";
public static final int DEFAULT_MAX_UP_BW = 8; //KBps
public static final int MAX_CONNECTIONS = 16; // per torrent
public I2PSnarkUtil(I2PAppContext ctx) {
_context = ctx;
@ -64,6 +66,7 @@ public class I2PSnarkUtil {
_configured = false;
_maxUploaders = Snark.MAX_TOTAL_UPLOADERS;
_maxUpBW = DEFAULT_MAX_UP_BW;
_maxConnections = MAX_CONNECTIONS;
}
/**
@ -87,8 +90,10 @@ public class I2PSnarkUtil {
public boolean configured() { return _configured; }
public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) {
_i2cpHost = i2cpHost;
_i2cpPort = i2cpPort;
if (i2cpHost != null)
_i2cpHost = i2cpHost;
if (i2cpPort > 0)
_i2cpPort = i2cpPort;
if (opts != null)
_opts.putAll(opts);
_configured = true;
@ -104,6 +109,11 @@ public class I2PSnarkUtil {
_configured = true;
}
public void setMaxConnections(int limit) {
_maxConnections = limit;
_configured = true;
}
public String getI2CPHost() { return _i2cpHost; }
public int getI2CPPort() { return _i2cpPort; }
public Map getI2CPOptions() { return _opts; }
@ -112,6 +122,7 @@ public class I2PSnarkUtil {
public boolean getEepProxySet() { return _shouldProxy; }
public int getMaxUploaders() { return _maxUploaders; }
public int getMaxUpBW() { return _maxUpBW; }
public int getMaxConnections() { return _maxConnections; }
/**
* Connect to the router, if we aren't already

View File

@ -44,7 +44,6 @@ public class PeerCoordinator implements PeerListener
// package local for access by CheckDownLoadersTask
final static long CHECK_PERIOD = 40*1000; // 40 seconds
final static int MAX_CONNECTIONS = 16;
final static int MAX_UPLOADERS = 6;
// Approximation of the number of current uploaders.
@ -237,7 +236,7 @@ public class PeerCoordinator implements PeerListener
{
synchronized(peers)
{
return !halted && peers.size() < MAX_CONNECTIONS;
return !halted && peers.size() < _util.getMaxConnections();
}
}
@ -295,7 +294,7 @@ public class PeerCoordinator implements PeerListener
peer.disconnect(false); // Don't deregister this connection/peer.
}
// This is already checked in addPeer() but we could have gone over the limit since then
else if (peers.size() >= MAX_CONNECTIONS)
else if (peers.size() >= _util.getMaxConnections())
{
if (_log.shouldLog(Log.WARN))
_log.warn("Already at MAX_CONNECTIONS in connected() with peer: " + peer);
@ -351,7 +350,7 @@ public class PeerCoordinator implements PeerListener
peersize = peers.size();
// This isn't a strict limit, as we may have several pending connections;
// thus there is an additional check in connected()
need_more = (!peer.isConnected()) && peersize < MAX_CONNECTIONS;
need_more = (!peer.isConnected()) && peersize < _util.getMaxConnections();
// Check if we already have this peer before we build the connection
Peer old = peerIDInList(peer.getPeerID(), peers);
need_more = need_more && ((old == null) || (old.getInactiveTime() > 8*60*1000));
@ -379,7 +378,7 @@ public class PeerCoordinator implements PeerListener
if (peer.isConnected())
_log.info("Add peer already connected: " + peer);
else
_log.info("Connections: " + peersize + "/" + MAX_CONNECTIONS
_log.info("Connections: " + peersize + "/" + _util.getMaxConnections()
+ " not accepting extra peer: " + peer);
}
return false;

View File

@ -28,6 +28,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.StringTokenizer;
@ -35,6 +36,7 @@ import java.util.Timer;
import java.util.TimerTask;
import net.i2p.I2PAppContext;
import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.data.Destination;
import net.i2p.util.I2PThread;
@ -235,6 +237,7 @@ public class Snark
}
}
public static final String PROP_MAX_CONNECTIONS = "i2psnark.maxConnections";
public String torrent;
public MetaInfo meta;
public Storage storage;
@ -254,10 +257,35 @@ public class Snark
this(util, torrent, ip, user_port, slistener, clistener, null, null, null, true, ".");
}
/** single torrent */
Snark(I2PAppContext ctx, String torrent, String ip, int user_port,
StorageListener slistener, CoordinatorListener clistener) {
this(new I2PSnarkUtil(ctx), torrent, ip, user_port, slistener, clistener, null, null, null, true, ".");
/** single torrent - via router */
public Snark(I2PAppContext ctx, Properties opts, String torrent,
StorageListener slistener, boolean start, String rootDir) {
this(new I2PSnarkUtil(ctx), torrent, null, -1, slistener, null, null, null, null, false, rootDir);
String host = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_HOST);
int port = 0;
String s = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_PORT);
if (s != null) {
try {
port = Integer.parseInt(s);
} catch (NumberFormatException nfe) {}
}
_util.setI2CPConfig(host, port, opts);
s = opts.getProperty(SnarkManager.PROP_UPBW_MAX);
if (s != null) {
try {
int v = Integer.parseInt(s);
_util.setMaxUpBW(v);
} catch (NumberFormatException nfe) {}
}
s = opts.getProperty(PROP_MAX_CONNECTIONS);
if (s != null) {
try {
int v = Integer.parseInt(s);
_util.setMaxConnections(v);
} catch (NumberFormatException nfe) {}
}
if (start)
this.startTorrent();
}
/** multitorrent */
@ -523,6 +551,8 @@ public class Snark
}
if (pc != null && _peerCoordinatorSet != null)
_peerCoordinatorSet.remove(pc);
if (_peerCoordinatorSet == null)
_util.disconnect();
}
static Snark parseArguments(String[] args)

View File

@ -32,7 +32,7 @@ public class SnarkManager implements Snark.CompleteListener {
/** map of (canonical) filename to Snark instance (unsynchronized) */
private Map _snarks;
private Object _addSnarkLock;
private String _configFile;
private String _configFile = "i2psnark.config";
private Properties _config;
private I2PAppContext _context;
private Log _log;
@ -67,9 +67,15 @@ public class SnarkManager implements Snark.CompleteListener {
_log = _context.logManager().getLog(SnarkManager.class);
_messages = new ArrayList(16);
_util = new I2PSnarkUtil(_context);
loadConfig(null);
}
/** Caller _must_ call loadConfig(file) before this if setting new values
* for i2cp host/port or i2psnark.dir
*/
public void start() {
_peerCoordinatorSet = new PeerCoordinatorSet();
_connectionAcceptor = new ConnectionAcceptor(_util);
loadConfig("i2psnark.config");
int minutes = getStartupDelayMinutes();
_messages.add("Adding torrents in " + minutes + (minutes == 1 ? " minute" : " minutes"));
I2PAppThread monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor");
@ -114,17 +120,20 @@ public class SnarkManager implements Snark.CompleteListener {
return new File(dir);
}
/** null to set initial defaults */
public void loadConfig(String filename) {
_configFile = filename;
if (_config == null)
_config = new Properties();
File cfg = new File(filename);
if (cfg.exists()) {
try {
DataHelper.loadProps(_config, cfg);
} catch (IOException ioe) {
_log.error("Error loading I2PSnark config '" + filename + "'", ioe);
}
if (filename != null) {
_configFile = filename;
File cfg = new File(filename);
if (cfg.exists()) {
try {
DataHelper.loadProps(_config, cfg);
} catch (IOException ioe) {
_log.error("Error loading I2PSnark config '" + filename + "'", ioe);
}
}
}
// now add sane defaults
if (!_config.containsKey(PROP_I2CP_HOST))

View File

@ -55,6 +55,7 @@ public class I2PSnarkServlet extends HttpServlet {
if ( (configFile == null) || (configFile.trim().length() <= 0) )
configFile = "i2psnark.config";
_manager.loadConfig(configFile);
_manager.start();
}
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {