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);
|
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
|
// not really listeners but the easiest way to get back to an optional SnarkManager
|
||||||
public long getSavedTorrentTime(Snark snark);
|
public long getSavedTorrentTime(Snark snark);
|
||||||
public BitField getSavedTorrentBitField(Snark snark);
|
public BitField getSavedTorrentBitField(Snark snark);
|
||||||
|
@ -515,8 +515,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
peerCount = peers.size();
|
peerCount = peers.size();
|
||||||
unchokePeer();
|
unchokePeer();
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (toDisconnect != null) {
|
if (toDisconnect != null) {
|
||||||
@ -652,8 +652,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
*/
|
*/
|
||||||
public boolean gotHave(Peer peer, int piece)
|
public boolean gotHave(Peer peer, int piece)
|
||||||
{
|
{
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
|
|
||||||
synchronized(wantedPieces) {
|
synchronized(wantedPieces) {
|
||||||
for (Piece pc : wantedPieces) {
|
for (Piece pc : wantedPieces) {
|
||||||
@ -672,8 +672,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
*/
|
*/
|
||||||
public boolean gotBitField(Peer peer, BitField bitfield)
|
public boolean gotBitField(Peer peer, BitField bitfield)
|
||||||
{
|
{
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
|
|
||||||
boolean rv = false;
|
boolean rv = false;
|
||||||
synchronized(wantedPieces) {
|
synchronized(wantedPieces) {
|
||||||
@ -919,8 +919,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
{
|
{
|
||||||
uploaded += size;
|
uploaded += size;
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -930,8 +930,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
{
|
{
|
||||||
downloaded += size;
|
downloaded += size;
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1040,8 +1040,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Got choke(" + choke + "): " + peer);
|
_log.info("Got choke(" + choke + "): " + peer);
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gotInterest(Peer peer, boolean interest)
|
public void gotInterest(Peer peer, boolean interest)
|
||||||
@ -1060,8 +1060,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnected(Peer peer)
|
public void disconnected(Peer peer)
|
||||||
@ -1081,8 +1081,8 @@ class PeerCoordinator implements PeerListener
|
|||||||
peerCount = peers.size();
|
peerCount = peers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener != null)
|
//if (listener != null)
|
||||||
listener.peerChange(this, peer);
|
// listener.peerChange(this, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when a peer is removed, to prevent it from being used in
|
/** 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;
|
//private boolean allocating = false;
|
||||||
|
|
||||||
|
/** does nothing */
|
||||||
public void storageCreateFile(Storage storage, String name, long length)
|
public void storageCreateFile(Storage storage, String name, long length)
|
||||||
{
|
{
|
||||||
//if (allocating)
|
//if (allocating)
|
||||||
@ -1129,6 +1134,7 @@ public class Snark
|
|||||||
// How much storage space has been allocated
|
// How much storage space has been allocated
|
||||||
private long allocated = 0;
|
private long allocated = 0;
|
||||||
|
|
||||||
|
/** does nothing */
|
||||||
public void storageAllocated(Storage storage, long length)
|
public void storageAllocated(Storage storage, long length)
|
||||||
{
|
{
|
||||||
//allocating = true;
|
//allocating = true;
|
||||||
@ -1140,7 +1146,8 @@ public class Snark
|
|||||||
|
|
||||||
private boolean allChecked = false;
|
private boolean allChecked = false;
|
||||||
private boolean checking = false;
|
private boolean checking = false;
|
||||||
private boolean prechecking = true;
|
//private boolean prechecking = true;
|
||||||
|
|
||||||
public void storageChecked(Storage storage, int num, boolean checked)
|
public void storageChecked(Storage storage, int num, boolean checked)
|
||||||
{
|
{
|
||||||
//allocating = false;
|
//allocating = false;
|
||||||
@ -1158,6 +1165,8 @@ public class Snark
|
|||||||
if (!checking) {
|
if (!checking) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Got " + (checked ? "" : "BAD ") + "piece: " + num);
|
_log.info("Got " + (checked ? "" : "BAD ") + "piece: " + num);
|
||||||
|
if (completeListener != null)
|
||||||
|
completeListener.gotPiece(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1187,6 +1196,9 @@ public class Snark
|
|||||||
coordinator.setWantedPieces();
|
coordinator.setWantedPieces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////// End StorageListener methods
|
||||||
|
|
||||||
|
|
||||||
/** SnarkSnutdown callback unused */
|
/** SnarkSnutdown callback unused */
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
{
|
{
|
||||||
|
@ -1517,6 +1517,12 @@ public class SnarkManager implements CompleteListener {
|
|||||||
addMessage(message);
|
addMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Snark.CompleteListener method.
|
||||||
|
* @since 0.9.4
|
||||||
|
*/
|
||||||
|
public void gotPiece(Snark snark) {}
|
||||||
|
|
||||||
// End Snark.CompleteListeners
|
// End Snark.CompleteListeners
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package org.klomp.snark;
|
package org.klomp.snark;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.crypto.TrustedUpdate;
|
import net.i2p.crypto.TrustedUpdate;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.update.*;
|
import net.i2p.update.*;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.SimpleTimer2;
|
||||||
import net.i2p.util.VersionComparator;
|
import net.i2p.util.VersionComparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,15 +23,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
private final UpdateManager _umgr;
|
private final UpdateManager _umgr;
|
||||||
private final SnarkManager _smgr;
|
private final SnarkManager _smgr;
|
||||||
private final List<URI> _urls;
|
private final List<URI> _urls;
|
||||||
private final String _updateFile;
|
|
||||||
private volatile boolean _isRunning;
|
private volatile boolean _isRunning;
|
||||||
|
private volatile boolean _hasMetaInfo;
|
||||||
|
private volatile boolean _isComplete;
|
||||||
private final String _newVersion;
|
private final String _newVersion;
|
||||||
private ByteArrayOutputStream _baos;
|
|
||||||
private URI _currentURI;
|
private URI _currentURI;
|
||||||
private Snark _snark;
|
private Snark _snark;
|
||||||
private boolean _hasMetaInfo;
|
|
||||||
|
|
||||||
private static final long MAX_LENGTH = 30*1024*1024;
|
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,
|
public UpdateRunner(I2PAppContext ctx, UpdateManager umgr, SnarkManager smgr,
|
||||||
List<URI> uris, String newVersion) {
|
List<URI> uris, String newVersion) {
|
||||||
@ -43,7 +42,6 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
_smgr = smgr;
|
_smgr = smgr;
|
||||||
_urls = uris;
|
_urls = uris;
|
||||||
_newVersion = newVersion;
|
_newVersion = newVersion;
|
||||||
_updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////// begin UpdateTask methods
|
//////// begin UpdateTask methods
|
||||||
@ -79,7 +77,6 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
* If it is, get the whole thing.
|
* If it is, get the whole thing.
|
||||||
*/
|
*/
|
||||||
private void update() {
|
private void update() {
|
||||||
|
|
||||||
if (_urls.isEmpty()) {
|
if (_urls.isEmpty()) {
|
||||||
_umgr.notifyTaskFailed(this, "", null);
|
_umgr.notifyTaskFailed(this, "", null);
|
||||||
return;
|
return;
|
||||||
@ -93,9 +90,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
String name = magnet.getName();
|
String name = magnet.getName();
|
||||||
byte[] ih = magnet.getInfoHash();
|
byte[] ih = magnet.getInfoHash();
|
||||||
String trackerURL = magnet.getTrackerURL();
|
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);
|
_snark = _smgr.addMagnet(name, ih, trackerURL, true, true, this);
|
||||||
if (_snark != null) {
|
if (_snark != null) {
|
||||||
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", updateURL) + "</b>");
|
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", updateURL) + "</b>");
|
||||||
|
new Timeout();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException iae) {}
|
} catch (IllegalArgumentException iae) {}
|
||||||
@ -104,6 +108,32 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
fatal("No valid URLs");
|
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) {
|
private void fatal(String error) {
|
||||||
if (_snark != null) {
|
if (_snark != null) {
|
||||||
if (_hasMetaInfo) {
|
if (_hasMetaInfo) {
|
||||||
@ -138,15 +168,21 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
}
|
}
|
||||||
_umgr.notifyComplete(this, _newVersion, f);
|
_umgr.notifyComplete(this, _newVersion, f);
|
||||||
_smgr.torrentComplete(snark);
|
_smgr.torrentComplete(snark);
|
||||||
|
_isComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called by stopTorrent() among others
|
||||||
|
*/
|
||||||
public void updateStatus(Snark snark) {
|
public void updateStatus(Snark snark) {
|
||||||
|
if (snark.isStopped()) {
|
||||||
|
if (!_isComplete)
|
||||||
|
fatal("stopped by user");
|
||||||
|
}
|
||||||
_smgr.updateStatus(snark);
|
_smgr.updateStatus(snark);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String gotMetaInfo(Snark snark) {
|
public String gotMetaInfo(Snark snark) {
|
||||||
Storage storage = snark.getStorage();
|
|
||||||
MetaInfo info = snark.getMetaInfo();
|
MetaInfo info = snark.getMetaInfo();
|
||||||
if (info.getFiles() != null) {
|
if (info.getFiles() != null) {
|
||||||
fatal("more than 1 file");
|
fatal("more than 1 file");
|
||||||
@ -173,6 +209,16 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
|||||||
_smgr.addMessage(snark, message);
|
_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) {
|
public long getSavedTorrentTime(Snark snark) {
|
||||||
return _smgr.getSavedTorrentTime(snark);
|
return _smgr.getSavedTorrentTime(snark);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user