Use the mirror as a peer when there are few peers for a file.
authorCameron Dale <camrdale@gmail.com>
Mon, 14 Apr 2008 03:18:17 +0000 (20:18 -0700)
committerCameron Dale <camrdale@gmail.com>
Mon, 14 Apr 2008 03:18:17 +0000 (20:18 -0700)
apt-p2p.conf
apt_p2p/HTTPDownloader.py
apt_p2p/PeerManager.py
apt_p2p/apt_p2p_conf.py
debian/apt-p2p.conf.sgml
test.py

index 249de43..6121547 100644 (file)
@@ -22,6 +22,12 @@ PORT = 9977
 # Set this to 0 to not limit the upload bandwidth.
 UPLOAD_LIMIT = 0
 
+# The minimum number of peers before the mirror is not used.
+# If there are fewer peers than this for a file, the mirror will also be
+# used to speed up the download. Set to 0 to never use the mirror if
+# there are peers.
+MIN_DOWNLOAD_PEERS = 3
+
 # Directory to store the downloaded files in
 CACHE_DIR = /var/cache/apt-p2p
     
index 15ee564..057b5a2 100644 (file)
@@ -31,6 +31,7 @@ class Peer(ClientFactory):
     def __init__(self, host, port=80):
         self.host = host
         self.port = port
+        self.mirror = False
         self.rank = 0.5
         self.busy = False
         self.pipeline = False
@@ -47,7 +48,7 @@ class Peer(ClientFactory):
         self._responseTimes = []
     
     def __repr__(self):
-        return "(%s, %d, %0.5f)" % (self.host, self.port, self.rank)
+        return "(%r, %r, %r)" % (self.host, self.port, self.rank)
         
     #{ Manage the request queue
     def connect(self):
index e19c7b4..e9d1ecb 100644 (file)
@@ -17,6 +17,7 @@ from HTTPDownloader import Peer
 from util import uncompact
 from Hash import PIECE_SIZE
 from apt_p2p_Khashmir.bencode import bdecode
+from apt_p2p_conf import config
 
 class GrowingFileStream(stream.FileStream):
     """Modified to stream data from a file as it becomes available.
@@ -261,6 +262,7 @@ class FileDownload:
         self.compact_peers = compact_peers
         
         self.path = '/~/' + quote_plus(hash.expected())
+        self.mirror_path = None
         self.pieces = None
         self.started = False
         
@@ -486,6 +488,16 @@ class FileDownload:
         assert self.pieces, "You must initialize the piece hashes first"
         self.peerlist = [self.peers[site]['peer'] for site in self.peers]
         
+        # Use the mirror if there are few peers
+        if len(self.peerlist) < config.getint('DEFAULT', 'MIN_DOWNLOAD_PEERS'):
+            parsed = urlparse(self.mirror)
+            if parsed[0] == "http":
+                site = splitHostPort(parsed[0], parsed[1])
+                self.mirror_path = urlunparse(('', '') + parsed[2:])
+                peer = self.manager.getPeer(site)
+                peer.mirror = True
+                self.peerlist.append(peer)
+        
         # Special case if there's only one good peer left
 #        if len(self.peerlist) == 1:
 #            log.msg('Downloading from peer %r' % (self.peerlist[0], ))
@@ -518,7 +530,10 @@ class FileDownload:
                 log.msg('Sending a request for piece %d to peer %r' % (piece, peer))
                 
                 self.outstanding += 1
-                df = peer.getRange(self.path, piece*PIECE_SIZE, (piece+1)*PIECE_SIZE - 1)
+                if peer.mirror:
+                    df = peer.getRange(self.mirror_path, piece*PIECE_SIZE, (piece+1)*PIECE_SIZE - 1)
+                else:
+                    df = peer.getRange(self.path, piece*PIECE_SIZE, (piece+1)*PIECE_SIZE - 1)
                 reactor.callLater(0, df.addCallbacks,
                                   *(self._getPiece, self._getError),
                                   **{'callbackArgs': (piece, peer),
@@ -635,6 +650,7 @@ class PeerManager:
             site = splitHostPort(parsed[0], parsed[1])
             path = urlunparse(('', '') + parsed[2:])
             peer = self.getPeer(site)
+            peer.mirror = True
             return peer.get(path, method, modtime)
 #        elif len(peers) == 1:
 #            site = uncompact(peers[0]['c'])
index fe56d7c..69f6a9c 100644 (file)
@@ -44,6 +44,12 @@ DEFAULTS = {
     # Set this to 0 to not limit the upload bandwidth.
     'UPLOAD_LIMIT': '0',
 
+    # The minimum number of peers before the mirror is not used.
+    # If there are fewer peers than this for a file, the mirror will also be
+    # used to speed up the download. Set to 0 to never use the mirror if
+    # there are peers.
+    'MIN_DOWNLOAD_PEERS': '3',
+
     # Directory to store the downloaded files in
     'CACHE_DIR': home + '/.apt-p2p/cache',
     
index ce99137..722de01 100644 (file)
            </listitem>
          </varlistentry>
          <varlistentry>
+           <term><option>MIN_DOWNLOAD_PEERS = <replaceable>number</replaceable></option></term>
+            <listitem>
+             <para>The minimum <replaceable>number</replaceable> of peers before the mirror is not used.
+               If there are fewer peers than this for a file, the mirror will also be
+               used to speed up the download. Set to 0 to never use the mirror if
+               there are peers.                
+               (Default is 3)</para>
+           </listitem>
+         </varlistentry>
+         <varlistentry>
            <term><option>CACHE_DIR = <replaceable>directory</replaceable></option></term>
             <listitem>
              <para>The <replaceable>directory</replaceable> to store the downloaded files in.
diff --git a/test.py b/test.py
index acbeeae..3ccaa14 100755 (executable)
--- a/test.py
+++ b/test.py
@@ -343,6 +343,12 @@ PORT = %(PORT)s
 # Set this to 0 to not limit the upload bandwidth.
 UPLOAD_LIMIT = 100
 
+# The minimum number of peers before the mirror is not used.
+# If there are fewer peers than this for a file, the mirror will also be
+# used to speed up the download. Set to 0 to never use the mirror if
+# there are peers.
+MIN_DOWNLOAD_PEERS = 3
+
 # Directory to store the downloaded files in
 CACHE_DIR = %(CACHE_DIR)s