* i2psnark:

- Add torrent auto-stop support; enable for update file
   - Add tunnel auto-close when no torrents are running
   - Log/msg tweaks on add/create failures
This commit is contained in:
zzz
2013-10-04 16:40:14 +00:00
parent e04cf132cc
commit e755051ebe
7 changed files with 70 additions and 10 deletions

View File

@ -26,10 +26,12 @@ class IdleChecker extends SimpleTimer2.TimedEvent {
private final PeerCoordinatorSet _pcs; private final PeerCoordinatorSet _pcs;
private final Log _log; private final Log _log;
private int _consec; private int _consec;
private int _consecNotRunning;
private boolean _isIdle; private boolean _isIdle;
private static final long CHECK_TIME = 63*1000; private static final long CHECK_TIME = 63*1000;
private static final int MAX_CONSEC_IDLE = 4; private static final int MAX_CONSEC_IDLE = 4;
private static final int MAX_CONSEC_NOT_RUNNING = 20;
/** /**
* Caller must schedule * Caller must schedule
@ -43,13 +45,30 @@ class IdleChecker extends SimpleTimer2.TimedEvent {
public void timeReached() { public void timeReached() {
if (_util.connected()) { if (_util.connected()) {
boolean torrentRunning = false;
boolean hasPeers = false; boolean hasPeers = false;
for (PeerCoordinator pc : _pcs) { for (PeerCoordinator pc : _pcs) {
if (pc.getPeers() > 0) { if (!pc.halted()) {
hasPeers = true; torrentRunning = true;
break; if (pc.getPeers() > 0) {
hasPeers = true;
break;
}
} }
} }
if (torrentRunning) {
_consecNotRunning = 0;
} else {
if (_consecNotRunning++ >= MAX_CONSEC_NOT_RUNNING) {
if (_log.shouldLog(Log.WARN))
_log.warn("Closing tunnels on idle");
_util.disconnect();
schedule(3 * CHECK_TIME);
return;
}
}
if (hasPeers) { if (hasPeers) {
if (_isIdle) if (_isIdle)
restoreTunnels(); restoreTunnels();
@ -62,6 +81,7 @@ class IdleChecker extends SimpleTimer2.TimedEvent {
} else { } else {
_isIdle = false; _isIdle = false;
_consec = 0; _consec = 0;
_consecNotRunning = 0;
} }
schedule(CHECK_TIME); schedule(CHECK_TIME);
} }

View File

@ -237,6 +237,7 @@ public class Snark
private final PeerCoordinatorSet _peerCoordinatorSet; private final PeerCoordinatorSet _peerCoordinatorSet;
private String trackerProblems; private String trackerProblems;
private int trackerSeenPeers; private int trackerSeenPeers;
private boolean _autoStoppable;
/** from main() via parseArguments() single torrent */ /** from main() via parseArguments() single torrent */
@ -905,6 +906,16 @@ public class Snark
return additionalTrackerURL; return additionalTrackerURL;
} }
/**
* @since 0.9.9
*/
public boolean isAutoStoppable() { return _autoStoppable; }
/**
* @since 0.9.9
*/
public void setAutoStoppable(boolean yes) { _autoStoppable = yes; }
/** /**
* Sets debug, ip and torrent variables then creates a Snark * Sets debug, ip and torrent variables then creates a Snark
* instance. Calls usage(), which terminates the program, if * instance. Calls usage(), which terminates the program, if

View File

@ -1666,8 +1666,8 @@ public class SnarkManager implements CompleteListener {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("DirMon found: " + DataHelper.toString(foundNames) + " existing: " + DataHelper.toString(existingNames)); _log.debug("DirMon found: " + DataHelper.toString(foundNames) + " existing: " + DataHelper.toString(existingNames));
// lets find new ones first... // lets find new ones first...
for (int i = 0; i < foundNames.size(); i++) { for (String name : foundNames) {
if (existingNames.contains(foundNames.get(i))) { if (existingNames.contains(name)) {
// already known. noop // already known. noop
} else { } else {
if (shouldAutoStart() && !_util.connect()) if (shouldAutoStart() && !_util.connect())
@ -1675,9 +1675,10 @@ public class SnarkManager implements CompleteListener {
try { try {
// Snark.fatal() throws a RuntimeException // Snark.fatal() throws a RuntimeException
// don't let one bad torrent kill the whole loop // don't let one bad torrent kill the whole loop
addTorrent(foundNames.get(i), !shouldAutoStart()); addTorrent(name, !shouldAutoStart());
} catch (Exception e) { } catch (Exception e) {
addMessage(_("Unable to add {0}", foundNames.get(i)) + ": " + e); addMessage(_("Error: Could not add the torrent {0}", name) + ": " + e.getMessage());
_log.error("Unable to add the torrent " + name, e);
} }
} }
} }

View File

@ -113,6 +113,7 @@ public class TrackerClient implements Runnable {
private long lastDHTAnnounce; private long lastDHTAnnounce;
private final List<TCTracker> trackers; private final List<TCTracker> trackers;
private final List<TCTracker> backupTrackers; private final List<TCTracker> backupTrackers;
private long _startedOn;
/** /**
* Call start() to start it. * Call start() to start it.
@ -334,6 +335,7 @@ public class TrackerClient implements Runnable {
} }
} }
this.completed = coordinator.getLeft() == 0; this.completed = coordinator.getLeft() == 0;
_startedOn = _util.getContext().clock().now();
} }
/** /**
@ -482,12 +484,30 @@ public class TrackerClient implements Runnable {
consecutiveFails = 0; consecutiveFails = 0;
runStarted = true; runStarted = true;
tr.started = true; tr.started = true;
Set<Peer> peers = info.getPeers();
tr.seenPeers = info.getPeerCount(); tr.seenPeers = info.getPeerCount();
if (snark.getTrackerSeenPeers() < tr.seenPeers) // update rising number quickly if (snark.getTrackerSeenPeers() < tr.seenPeers) // update rising number quickly
snark.setTrackerSeenPeers(tr.seenPeers); snark.setTrackerSeenPeers(tr.seenPeers);
// auto stop
// These are very high thresholds for now, not configurable,
// just for update torrent
if (completed &&
tr.isPrimary &&
snark.isAutoStoppable() &&
!snark.isChecking() &&
info.getSeedCount() > 100 &&
coordinator.getPeerCount() <= 0 &&
_util.getContext().clock().now() > _startedOn + 2*60*60*1000 &&
uploaded >= 2 * snark.getTotalLength()) {
if (_log.shouldLog(Log.WARN))
_log.warn("Auto stopping " + snark.getBaseName());
snark.setAutoStoppable(false);
snark.stopTorrent();
return tr.seenPeers;
}
Set<Peer> peers = info.getPeers();
// pass everybody over to our tracker // pass everybody over to our tracker
DHT dht = _util.getDHT(); DHT dht = _util.getDHT();
if (dht != null) { if (dht != null) {

View File

@ -190,6 +190,12 @@ class TrackerInfo
return Math.max(pc, complete + incomplete - 1); return Math.max(pc, complete + incomplete - 1);
} }
/** @since 0.9.9 */
public int getSeedCount()
{
return complete;
}
public String getFailureReason() public String getFailureReason()
{ {
return failure_reason; return failure_reason;

View File

@ -264,6 +264,7 @@ class UpdateRunner implements UpdateTask, CompleteListener {
} }
_hasMetaInfo = true; _hasMetaInfo = true;
notifyProgress(); notifyProgress();
snark.setAutoStoppable(true);
return _smgr.gotMetaInfo(snark); return _smgr.gotMetaInfo(snark);
} }

View File

@ -976,7 +976,8 @@ public class I2PSnarkServlet extends BasicServlet {
if (announceURL != null && !_manager.util().getOpenTrackers().contains(announceURL)) if (announceURL != null && !_manager.util().getOpenTrackers().contains(announceURL))
_manager.addMessage(_("Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\"", baseFile.getName())); _manager.addMessage(_("Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\"", baseFile.getName()));
} catch (IOException ioe) { } catch (IOException ioe) {
_manager.addMessage(_("Error creating a torrent for \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe.getMessage()); _manager.addMessage(_("Error creating a torrent for \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe);
_log.error("Error creating a torrent", ioe);
} }
} else { } else {
_manager.addMessage(_("Cannot create a torrent for the nonexistent data: {0}", baseFile.getAbsolutePath())); _manager.addMessage(_("Cannot create a torrent for the nonexistent data: {0}", baseFile.getAbsolutePath()));