forked from I2P_Developers/i2p.i2p
- Add fail timers
- Add progress indication - Listener cleanup
This commit is contained in:
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user