[mnet-devel] patch: better blockwrangling strategy

Zooko O'Whielacronx zooko at zooko.com
Tue Feb 17 17:02:14 GMT 2004


This backs off from stalled downloads.  It also improves downloads in another 
way: how do you decide which peer to query next in the hunt for blocks?  Before 
this patch, there was a very complicated sorting algorithm which, among other 
things, forced peers that you had already queried to be at the end of the list.  
Then there was a random selection which was biased towards the front of the 
list.  The only thing this patch does is get rid of the random selection and 
just take the front peer from the list.  Since he goes to the back of the list 
once he has been queried, this guarantees that we march through all peers 
instead of randomly trying different ones each time, possibly redundantly.

The theoretical improvement is significant.  (With the old way, it could be an 
awful long time before you ever got around to trying the peer who had the block 
you needed, and this awful long time would increase greatly with the number of 
peers on the network.)

On the other hand, it isn't absolutely required for correct operation.  The 
download would eventually work anyway without this patch.  (Unless of course the 
relevant peer went off-line before you got around to it.)

I've tested this patch.

--- common/BlockWrangler.py	7 Dec 2003 17:35:50 -0000	1.94
+++ common/BlockWrangler.py	17 Feb 2004 16:06:37 -0000
@@ -536,8 +537,7 @@ class BlockWrangler(nummedobj.NummedObj)
         """
         @return: a list of peerIds;  This omits peers which currently have an
             outstanding "do you have blocks" transaction, and it sorts the peers in
-            order of preference for the "do you have blocks" transaction.
         """
         assert self.data._assert_consistency()
         peerIds = self.mtm._peerman.get_servers("block server")
--- common/BlockWranglingStrategy.py	7 Dec 2003 17:35:50 -0000	1.33
+++ common/BlockWranglingStrategy.py	17 Feb 2004 16:06:37 -0000
@@ -119,7 +119,7 @@ class GSR(BlockWranglingStrategy):
         return false
         
     def _try_to_find_more_blocks(self):
-        # To which peer?  Well, we'll pick a random peer, but weighted towards our favorites (exponential distribution, in fact).
+        # To which peer?  The peers are sorted increasing order of how many times we have already asked them for blocks, so just taking the first one will make sure we try all of them in order.
         peerIds = self.blockwrangler.list_sorted_peers_without_outstanding_searches()
         origpeerIds = copy.copy(peerIds) # for consistency check
         if len(peerIds) == 0:
@@ -128,17 +128,13 @@ class GSR(BlockWranglingStrategy):
             self.schedule_event(delay=15*60) # Now iterate -- this schedules another call to `event()' to happen ASAP after 15 minutes from now on the DoQ.
             return
 
-        while len(peerIds) > 0: # Note: there is a "return" in here that usually exits this loop.
-            index = int(randutil.random()**2 * len(peerIds)) # This picks a random peer, but more likely one towards front of the list.
-            peerId = peerIds[index]
-            del peerIds[index]
+        while peerIds: # Note: there is a "return" in here that usually exits this loop.
+            peerId = peerIds.pop(0)
             (blockIds, minimalalreadytried,) = choose_closest_wanted_blocks(self.blockwrangler, peerId)
             if len(blockIds) > 0:
-                debugprint("%s: searching on peer %s (delay %s) for blocks %s\n", args=(self, peerId, minimalalreadytried, blockIds,), v=4, vs="BlockWranglingStrategy")
-                DoQ.doq.add_task(self.blockwrangler.look_for_blocks_on_peer, args=(peerId, blockIds,), delay=minimalalreadytried)
-                debugprint("%s scheduling next event, delay: %s, because: %s\n", args=(self, 3.0, "issued search",), v=7, vs="BlockWranglingStrategy")
-                self.schedule_event(delay=minimalalreadytried) # Now iterate -- this schedules another call to event() to happen later on the DoQ.
+                debugprint("%s: searching on peer %s (and then delay %s) for blocks %s\n", args=(self, peerId, minimalalreadytried, blockIds,), v=4, vs="BlockWranglingStrategy")
+                DoQ.doq.add_task(self.blockwrangler.look_for_blocks_on_peer, args=(peerId, blockIds, minimalalreadytried))
                 return # We initiated a look_for_blocks_on_peer() -- no need to iterate this while loop more.
 
         # consistency check: if we reach this code then there must not be any peers that we are not querying (or downloading from) right now!  Or else there must not be any blocks that we want.


-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
mnet-devel mailing list
mnet-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mnet-devel




More information about the Mnet-devel mailing list