- Add fail timers

- Add progress indication
- Listener cleanup
This commit is contained in:
zzz
2012-10-22 14:51:41 +00:00
parent 8b2889e317
commit 95e0c37222
5 changed files with 96 additions and 27 deletions

View File

@ -49,6 +49,11 @@ public interface CompleteListener {
*/
public void addMessage(Snark snark, String message);
/**
* @since 0.9.4
*/
public void gotPiece(Snark snark);
// not really listeners but the easiest way to get back to an optional SnarkManager
public long getSavedTorrentTime(Snark snark);
public BitField getSavedTorrentBitField(Snark snark);

View File

@ -515,8 +515,8 @@ class PeerCoordinator implements PeerListener
peerCount = peers.size();
unchokePeer();
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
}
if (toDisconnect != null) {
@ -652,8 +652,8 @@ class PeerCoordinator implements PeerListener
*/
public boolean gotHave(Peer peer, int piece)
{
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
synchronized(wantedPieces) {
for (Piece pc : wantedPieces) {
@ -672,8 +672,8 @@ class PeerCoordinator implements PeerListener
*/
public boolean gotBitField(Peer peer, BitField bitfield)
{
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
boolean rv = false;
synchronized(wantedPieces) {
@ -919,8 +919,8 @@ class PeerCoordinator implements PeerListener
{
uploaded += size;
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
/**
@ -930,8 +930,8 @@ class PeerCoordinator implements PeerListener
{
downloaded += size;
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
/**
@ -1040,8 +1040,8 @@ class PeerCoordinator implements PeerListener
if (_log.shouldLog(Log.INFO))
_log.info("Got choke(" + choke + "): " + peer);
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
public void gotInterest(Peer peer, boolean interest)
@ -1060,8 +1060,8 @@ class PeerCoordinator implements PeerListener
}
}
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
public void disconnected(Peer peer)
@ -1081,8 +1081,8 @@ class PeerCoordinator implements PeerListener
peerCount = peers.size();
}
if (listener != null)
listener.peerChange(this, peer);
//if (listener != null)
// listener.peerChange(this, peer);
}
/** Called when a peer is removed, to prevent it from being used in

View File

@ -1115,7 +1115,12 @@ public class Snark
}
}
///////////// Begin StorageListener methods
//private boolean allocating = false;
/** does nothing */
public void storageCreateFile(Storage storage, String name, long length)
{
//if (allocating)
@ -1129,6 +1134,7 @@ public class Snark
// How much storage space has been allocated
private long allocated = 0;
/** does nothing */
public void storageAllocated(Storage storage, long length)
{
//allocating = true;
@ -1140,7 +1146,8 @@ public class Snark
private boolean allChecked = false;
private boolean checking = false;
private boolean prechecking = true;
//private boolean prechecking = true;
public void storageChecked(Storage storage, int num, boolean checked)
{
//allocating = false;
@ -1158,6 +1165,8 @@ public class Snark
if (!checking) {
if (_log.shouldLog(Log.INFO))
_log.info("Got " + (checked ? "" : "BAD ") + "piece: " + num);
if (completeListener != null)
completeListener.gotPiece(this);
}
}
@ -1187,6 +1196,9 @@ public class Snark
coordinator.setWantedPieces();
}
///////////// End StorageListener methods
/** SnarkSnutdown callback unused */
public void shutdown()
{

View File

@ -1517,6 +1517,12 @@ public class SnarkManager implements CompleteListener {
addMessage(message);
}
/**
* A Snark.CompleteListener method.
* @since 0.9.4
*/
public void gotPiece(Snark snark) {}
// End Snark.CompleteListeners
/**

View File

@ -1,17 +1,15 @@
package org.klomp.snark;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.crypto.TrustedUpdate;
import net.i2p.data.DataHelper;
import net.i2p.update.*;
import net.i2p.util.Log;
import net.i2p.util.SimpleTimer2;
import net.i2p.util.VersionComparator;
/**
@ -25,15 +23,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
private final UpdateManager _umgr;
private final SnarkManager _smgr;
private final List<URI> _urls;
private final String _updateFile;
private volatile boolean _isRunning;
private volatile boolean _hasMetaInfo;
private volatile boolean _isComplete;
private final String _newVersion;
private ByteArrayOutputStream _baos;
private URI _currentURI;
private Snark _snark;
private boolean _hasMetaInfo;
private static final long MAX_LENGTH = 30*1024*1024;
private static final long METAINFO_TIMEOUT = 30*60*1000;
private static final long COMPLETE_TIMEOUT = 3*60*60*1000;
public UpdateRunner(I2PAppContext ctx, UpdateManager umgr, SnarkManager smgr,
List<URI> uris, String newVersion) {
@ -43,7 +42,6 @@ class UpdateRunner implements UpdateTask, CompleteListener {
_smgr = smgr;
_urls = uris;
_newVersion = newVersion;
_updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath();
}
//////// begin UpdateTask methods
@ -79,7 +77,6 @@ class UpdateRunner implements UpdateTask, CompleteListener {
* If it is, get the whole thing.
*/
private void update() {
if (_urls.isEmpty()) {
_umgr.notifyTaskFailed(this, "", null);
return;
@ -93,9 +90,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
String name = magnet.getName();
byte[] ih = magnet.getInfoHash();
String trackerURL = magnet.getTrackerURL();
if (trackerURL == null && !_smgr.util().shouldUseDHT() &&
!_smgr.util().shouldUseOpenTrackers()) {
// but won't we use OT as a failsafe even if disabled?
_umgr.notifyAttemptFailed(this, "No tracker, no DHT, no OT", null);
continue;
}
_snark = _smgr.addMagnet(name, ih, trackerURL, true, true, this);
if (_snark != null) {
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", updateURL) + "</b>");
new Timeout();
break;
}
} catch (IllegalArgumentException iae) {}
@ -104,6 +108,32 @@ class UpdateRunner implements UpdateTask, CompleteListener {
fatal("No valid URLs");
}
/**
* This will run twice, once at the metainfo timeout and
* once at the complete timeout.
*/
private class Timeout extends SimpleTimer2.TimedEvent {
private final long _start = _context.clock().now();
public Timeout() {
super(_context.simpleTimer2(), METAINFO_TIMEOUT);
}
public void timeReached() {
if (_isComplete || !_isRunning)
return;
if (!_hasMetaInfo) {
fatal("Metainfo timeout");
return;
}
if (_context.clock().now() - _start >= COMPLETE_TIMEOUT) {
fatal("Complete timeout");
return;
}
reschedule(COMPLETE_TIMEOUT - METAINFO_TIMEOUT);
}
}
private void fatal(String error) {
if (_snark != null) {
if (_hasMetaInfo) {
@ -138,15 +168,21 @@ class UpdateRunner implements UpdateTask, CompleteListener {
}
_umgr.notifyComplete(this, _newVersion, f);
_smgr.torrentComplete(snark);
_isComplete = true;
}
/**
* This is called by stopTorrent() among others
*/
public void updateStatus(Snark snark) {
if (snark.isStopped()) {
if (!_isComplete)
fatal("stopped by user");
}
_smgr.updateStatus(snark);
}
public String gotMetaInfo(Snark snark) {
Storage storage = snark.getStorage();
MetaInfo info = snark.getMetaInfo();
if (info.getFiles() != null) {
fatal("more than 1 file");
@ -173,6 +209,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
_smgr.addMessage(snark, message);
}
public void gotPiece(Snark snark) {
if (_hasMetaInfo) {
long total = snark.getTotalLength();
long remaining = snark.getRemainingLength();
String status = "<b>" + _smgr.util().getString("Updating") + "</b>";
_umgr.notifyProgress(this, status, total - remaining, total);
}
_smgr.gotPiece(snark);
}
public long getSavedTorrentTime(Snark snark) {
return _smgr.getSavedTorrentTime(snark);
}