forked from I2P_Developers/i2p.i2p
* i2psnark:
- Add idle detector, reduce tunnel count when idle (prep for torrent updates) - Cancel CoordinatorAcceptor cleaner when halted - Make PeerCoordinatorSet an Iterable - Reduce max protocol errors to 1 - Disable unused PeerMonitorTask
This commit is contained in:
120
apps/i2psnark/java/src/org/klomp/snark/IdleChecker.java
Normal file
120
apps/i2psnark/java/src/org/klomp/snark/IdleChecker.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
*/
|
||||
package org.klomp.snark;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
|
||||
/**
|
||||
* Periodically check for idle condition based on connected peers,
|
||||
* and reduce/restore tunnel count as necessary.
|
||||
* We can't use the I2CP idle detector because it's based on traffic,
|
||||
* so DHT and announces would keep it non-idle.
|
||||
*
|
||||
* @since 0.9.7
|
||||
*/
|
||||
class IdleChecker extends SimpleTimer2.TimedEvent {
|
||||
|
||||
private final I2PSnarkUtil _util;
|
||||
private final PeerCoordinatorSet _pcs;
|
||||
private final Log _log;
|
||||
private int _consec;
|
||||
private boolean _isIdle;
|
||||
|
||||
private static final long CHECK_TIME = 63*1000;
|
||||
private static final int MAX_CONSEC_IDLE = 4;
|
||||
|
||||
/**
|
||||
* Caller must schedule
|
||||
*/
|
||||
public IdleChecker(I2PSnarkUtil util, PeerCoordinatorSet pcs) {
|
||||
super(util.getContext().simpleTimer2());
|
||||
_log = util.getContext().logManager().getLog(IdleChecker.class);
|
||||
_util = util;
|
||||
_pcs = pcs;
|
||||
}
|
||||
|
||||
public void timeReached() {
|
||||
if (_util.connected()) {
|
||||
boolean hasPeers = false;
|
||||
for (PeerCoordinator pc : _pcs) {
|
||||
if (pc.getPeers() > 0) {
|
||||
hasPeers = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasPeers) {
|
||||
if (_isIdle)
|
||||
restoreTunnels();
|
||||
} else {
|
||||
if (!_isIdle) {
|
||||
if (_consec++ >= MAX_CONSEC_IDLE)
|
||||
reduceTunnels();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_isIdle = false;
|
||||
_consec = 0;
|
||||
}
|
||||
schedule(CHECK_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce to 1 in / 1 out tunnel
|
||||
*/
|
||||
private void reduceTunnels() {
|
||||
_isIdle = true;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Reducing tunnels on idle");
|
||||
setTunnels("1", "1", "0", "0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore tunnel count
|
||||
*/
|
||||
private void restoreTunnels() {
|
||||
_isIdle = false;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Restoring tunnels on activity");
|
||||
Map<String, String> opts = _util.getI2CPOptions();
|
||||
String i = opts.get("inbound.quantity");
|
||||
if (i == null)
|
||||
i = "3";
|
||||
String o = opts.get("outbound.quantity");
|
||||
if (o == null)
|
||||
o = "3";
|
||||
String ib = opts.get("inbound.backupQuantity");
|
||||
if (ib == null)
|
||||
ib = "0";
|
||||
String ob= opts.get("outbound.backupQuantity");
|
||||
if (ob == null)
|
||||
ob = "0";
|
||||
setTunnels(i, o, ib, ob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set in / out / in backup / out backup tunnel counts
|
||||
*/
|
||||
private void setTunnels(String i, String o, String ib, String ob) {
|
||||
_consec = 0;
|
||||
I2PSocketManager mgr = _util.getSocketManager();
|
||||
if (mgr != null) {
|
||||
I2PSession sess = mgr.getSession();
|
||||
if (sess != null) {
|
||||
Properties newProps = new Properties();
|
||||
newProps.setProperty("inbound.quantity", i);
|
||||
newProps.setProperty("outbound.quantity", o);
|
||||
newProps.setProperty("inbound.backupQuantity", ib);
|
||||
newProps.setProperty("outbound.backupQuantity", ob);
|
||||
sess.updateOptions(newProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user