Opened 3 years ago

Closed 16 months ago

#2288 closed defect (fixed)

Seeding torrents do not download new comments

Reported by: Reportage Owned by: zzz
Priority: minor Milestone: 0.9.46
Component: apps/i2psnark Version: 0.9.35
Keywords: i2psnark, comments Cc:
Parent Tickets: Sensitive: no


Once a torrent has been downloaded, no comments are downloaded thereafter. If new comments appear, they should automatically be downloaded if a torrent is being seeded.


Change History (4)

comment:1 Changed 3 years ago by zzz

True, more-or-less, and by design. Due to unfortunate combination of:

  • ut-comment is a flooding protocol, peers must be connected, there's no DHT
  • snark seed will never connect outbound
  • snark seed will refuse inbound connection from seed (and blacklist?)

If there's a ut-comment-capable leech in the swarm, he will bridge new comments between connected seeds. If not, there's no other mechanism.

I would have preferred to implement Vuze's DHT comment protocol, but it is much more complex, undocumented, and parg said it was too ugly to write up or reuse.

We could relax snark's seed-to-seed restrictions fairly easily, but we'd still need to implement some sort of periodic outbound connections to look for new comments, and that's harder.

comment:2 Changed 3 years ago by zzz

Don't immediately disconnect a seed that connects to seeds if it supports comments in 27a053fa8f7cd20a0c121b5c0335ce8e4b92ed0b to be 0.9.35-20.
By itself, this does nothing, as only snark supports comments and snark won't connect out as a seed, but it will allow us to successfully connect out in a future release.

comment:3 Changed 16 months ago by zzz

Milestone: undecided0.9.46
Sensitive: unset
Status: newaccepted

Please test the following patch. Will connect out at a random time within the first two hours of uptime, and then every 12 hours after that. Briefly tested here. Seems to work but I don't have any torrents with new comments out there.

I'm concerned that it may not behave right if all other peers in the torrent are bigly/vuze, as I don't think they support ut_comment? not sure…

# old_revision [7c2eff80242ed316d91bf94bc58e224df049e5ed]
# patch "apps/i2psnark/java/src/org/klomp/snark/"
#  from [2a442afdcf7c37fa500cb76b65fad8171c7fd841]
#    to [f069af28b214b2815b33ed45fa26e6078560c798]
--- apps/i2psnark/java/src/org/klomp/snark/	2a442afdcf7c37fa500cb76b65fad8171c7fd841
+++ apps/i2psnark/java/src/org/klomp/snark/	f069af28b214b2815b33ed45fa26e6078560c798
@@ -30,7 +30,6 @@ import java.util.Map;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -43,6 +42,7 @@ import net.i2p.util.Log;
 import net.i2p.util.ConcurrentHashSet;
 import net.i2p.util.I2PAppThread;
 import net.i2p.util.Log;
+import net.i2p.util.RandomSource;
 import net.i2p.util.SimpleTimer2;
 import org.klomp.snark.bencode.BEValue;
@@ -145,7 +145,11 @@ class PeerCoordinator implements PeerLis
   private final MagnetState magnetState;
   private final CoordinatorListener listener;
   private final I2PSnarkUtil _util;
-  private final Random _random;
+  private final RandomSource _random;
+  private final AtomicLong _commentsLastRequested = new AtomicLong();
+  private static final long COMMENT_REQ_INTERVAL = 12*60*60*1000L;
+  private static final long COMMENT_REQ_DELAY = 60*60*1000L;
    *  @param metainfo null if in magnet mode
@@ -176,6 +180,9 @@ class PeerCoordinator implements PeerLis
     // this will help the behavior with global limits
     timer = new CheckEvent(_util.getContext(), new PeerCheckerTask(_util, this));
     timer.schedule((CHECK_PERIOD / 2) + _random.nextInt((int) CHECK_PERIOD));
+    // we don't store the last-requested time, so just delay a random amount
+    _commentsLastRequested.set(util.getContext().clock().now() - (COMMENT_REQ_INTERVAL - _random.nextLong(COMMENT_REQ_DELAY)));
@@ -404,7 +411,9 @@ class PeerCoordinator implements PeerLis
   public boolean needOutboundPeers() {
         //return wantedBytes != 0 && needPeers();
         // minus two to make it a little easier for new peers to get in on large swarms
-        return wantedBytes != 0 &&
+        return (wantedBytes != 0 ||
+                (_util.utCommentsEnabled() &&
+                 _commentsLastRequested.get() < _util.getContext().clock().now() - COMMENT_REQ_INTERVAL)) &&
                !halted &&
                peers.size() < getMaxConnections() - 2 &&
                (storage == null || !storage.isChecking());
@@ -617,6 +626,8 @@ class PeerCoordinator implements PeerLis
             bitfield = storage.getBitField();
             bitfield = null;
+        if (!peer.isIncoming() && wantedBytes == 0 && _log.shouldInfo())
+  "Outbound connection as seed to get comments for " + snark.getBaseName() + " to " + peer);
         // if we aren't a seed but we don't want any more
         final boolean partialComplete = wantedBytes == 0 && bitfield != null && !bitfield.complete();
         Runnable r = new Runnable()
@@ -1466,6 +1477,7 @@ class PeerCoordinator implements PeerLis
               if (sz >= CommentSet.MAX_SIZE)
               ExtensionHandler.sendCommentReq(peer, CommentSet.MAX_SIZE - sz);
+              _commentsLastRequested.set(_util.getContext().clock().now());
       } catch (InvalidBEncodingException ibee) {}

comment:4 Changed 16 months ago by zzz

Resolution: fixed
Status: acceptedclosed

Vuze and Bigly do not advertise ut_comment.
Added counter to prevent excessive connections out to a swarm with no ut_comment peers.
In b71df950fcc490dccf806388f7d8374b592468d4 to be 0.9.45-11

Note: See TracTickets for help on using tickets.