Пример #1
0
 def _round_robin(self):
     self.schedule(self._round_robin, 5)
     if self.super_seed:
         cons = range(len(self.connections))
         to_close = []
         count = self.config['min_uploads']-self.last_preferred
         if count > 0:   # optimization
             shuffle(cons)
         for c in cons:
             i = self.picker.next_have(self.connections[c], count > 0)
             if i is None:
                 continue
             if i < 0:
                 to_close.append(self.connections[c])
                 continue
             self.connections[c].send_have(i)
             count -= 1
         for c in to_close:
             c.close()
     if self.last_round_robin + self.round_robin_period < clock():
         self.last_round_robin = clock()
         for i in xrange(1, len(self.connections)):
             c = self.connections[i]
             u = c.get_upload()
             if u.is_choked() and u.is_interested():
                 self.connections = self.connections[i:] + self.connections[:i]
                 break
     self._rechoke()
Пример #2
0
 def is_snubbed(self):
     if ( self.interested and not self.choked
          and clock() - self.last2 > self.downloader.snub_time ):
         for index, begin, length in self.active_requests:
             self.connection.send_cancel(index, begin, length)
         self.got_choke()    # treat it just like a choke
     return clock() - self.last > self.downloader.snub_time
Пример #3
0
 def _round_robin(self):
     self.schedule(self._round_robin, 5)
     if self.super_seed:
         cons = range(len(self.connections))
         to_close = []
         count = self.config['min_uploads'] - self.last_preferred
         if count > 0:  # optimization
             shuffle(cons)
         for c in cons:
             i = self.picker.next_have(self.connections[c], count > 0)
             if i is None:
                 continue
             if i < 0:
                 to_close.append(self.connections[c])
                 continue
             self.connections[c].send_have(i)
             count -= 1
         for c in to_close:
             c.close()
     if self.last_round_robin + self.round_robin_period < clock():
         self.last_round_robin = clock()
         for i in xrange(1, len(self.connections)):
             c = self.connections[i]
             u = c.get_upload()
             if u.is_choked() and u.is_interested():
                 self.connections = self.connections[
                     i:] + self.connections[:i]
                 break
     self._rechoke()
Пример #4
0
    def __init__(self, storage, picker, backlog, max_rate_period,
                 numpieces, chunksize, measurefunc, snub_time,
                 kickbans_ok, kickfunc, banfunc):
        self.storage = storage
        self.picker = picker
        self.backlog = backlog
        self.max_rate_period = max_rate_period
        self.measurefunc = measurefunc
        self.totalmeasure = Measure(max_rate_period*storage.piece_length/storage.request_size)
        self.numpieces = numpieces
        self.chunksize = chunksize
        self.snub_time = snub_time
        self.kickfunc = kickfunc
        self.banfunc = banfunc
        self.disconnectedseeds = {}
        self.downloads = []
        self.perip = {}
        self.gotbaddata = {}
        self.kicked = {}
        self.banned = {}
        self.kickbans_ok = kickbans_ok
        self.kickbans_halted = False
        self.super_seeding = False
        self.endgamemode = False
        self.endgame_queued_pieces = []
        self.all_requests = []
        self.discarded = 0L
#        self.download_rate = 25000  # 25K/s test rate
        self.download_rate = 0
        self.bytes_requested = 0
        self.last_time = clock()
        self.queued_out = {}
        self.requeueing = False
        self.paused = False
Пример #5
0
    def num_disconnected_seeds(self):
        # first expire old ones
        expired = []
        for id,t in self.disconnectedseeds.items():
            if clock() - t > EXPIRE_TIME:     #Expire old seeds after so long
                expired.append(id)
        for id in expired:
#            self.picker.seed_disappeared()
            del self.disconnectedseeds[id]
        return len(self.disconnectedseeds)
Пример #6
0
 def next_have(self, connection, looser_upload):
     if self.seed_time is None:
         self.seed_time = clock()
         return None
     if clock(
     ) < self.seed_time + 10:  # wait 10 seconds after seeing the first peers
         return None  # to give time to grab have lists
     if not connection.upload.super_seeding:
         return None
     olddl = self.seed_connections.get(connection)
     if olddl is None:
         ip = connection.get_ip()
         olddl = self.past_ips.get(ip)
         if olddl is not None:  # peer reconnected
             self.seed_connections[connection] = olddl
     if olddl is not None:
         if looser_upload:
             num = 1  # send a new have even if it hasn't spread that piece elsewhere
         else:
             num = 2
         if self.seed_got_haves[olddl] < num:
             return None
         if not connection.upload.was_ever_interested:  # it never downloaded it?
             connection.upload.skipped_count += 1
             if connection.upload.skipped_count >= 3:  # probably another stealthed seed
                 return -1  # signal to close it
     for tier in self.interests:
         for piece in tier:
             if not connection.download.have[piece]:
                 seedint = self.level_in_interests[piece]
                 self.level_in_interests[
                     piece] += 1  # tweak it up one, so you don't duplicate effort
                 if seedint == len(self.interests) - 1:
                     self.interests.append([])
                 self._shift_over(piece, self.interests[seedint],
                                  self.interests[seedint + 1])
                 self.seed_got_haves[piece] = 0  # reset this
                 self.seed_connections[connection] = piece
                 connection.upload.seed_have_list.append(piece)
                 return piece
     return -1  # something screwy; terminate connection
Пример #7
0
 def __init__(self, config, schedule, picker, done = lambda: False):
     self.config = config
     self.round_robin_period = config['round_robin_period']
     self.schedule = schedule
     self.picker = picker
     self.connections = []
     self.last_preferred = 0
     self.last_round_robin = clock()
     self.done = done
     self.super_seed = False
     self.paused = False
     schedule(self._round_robin, 5)
Пример #8
0
 def __init__(self, config, schedule, picker, done=lambda: False):
     self.config = config
     self.round_robin_period = config['round_robin_period']
     self.schedule = schedule
     self.picker = picker
     self.connections = []
     self.last_preferred = 0
     self.last_round_robin = clock()
     self.done = done
     self.super_seed = False
     self.paused = False
     schedule(self._round_robin, 5)
Пример #9
0
 def send_unchoke(self):
     if self.send_choke_queued:
         self.send_choke_queued = False
         if DEBUG:
             print 'CHOKE SUPPRESSED'
     else:
         self._send_message(UNCHOKE)
         if ( self.partial_message or self.just_unchoked is None
              or not self.upload.interested or self.download.active_requests ):
             self.just_unchoked = 0
         else:
             self.just_unchoked = clock()
Пример #10
0
 def send_unchoke(self):
     if self.send_choke_queued:
         self.send_choke_queued = False
         if DEBUG:
             print 'CHOKE SUPPRESSED'
     else:
         self._send_message(UNCHOKE)
         if (self.partial_message or self.just_unchoked is None
                 or not self.upload.interested
                 or self.download.active_requests):
             self.just_unchoked = 0
         else:
             self.just_unchoked = clock()
Пример #11
0
 def next_have(self, connection, looser_upload):
     if self.seed_time is None:
         self.seed_time = clock()
         return None
     if clock() < self.seed_time+10:  # wait 10 seconds after seeing the first peers
         return None                 # to give time to grab have lists
     if not connection.upload.super_seeding:
         return None
     olddl = self.seed_connections.get(connection)
     if olddl is None:
         ip = connection.get_ip()
         olddl = self.past_ips.get(ip)
         if olddl is not None:                               # peer reconnected
             self.seed_connections[connection] = olddl
     if olddl is not None:
         if looser_upload:
             num = 1     # send a new have even if it hasn't spread that piece elsewhere
         else:
             num = 2
         if self.seed_got_haves[olddl] < num:
             return None
         if not connection.upload.was_ever_interested:   # it never downloaded it?
             connection.upload.skipped_count += 1
             if connection.upload.skipped_count >= 3:    # probably another stealthed seed
                 return -1                               # signal to close it
     for tier in self.interests:
         for piece in tier:
             if not connection.download.have[piece]:
                 seedint = self.level_in_interests[piece]
                 self.level_in_interests[piece] += 1  # tweak it up one, so you don't duplicate effort
                 if seedint == len(self.interests) - 1:
                     self.interests.append([])
                 self._shift_over(piece,
                             self.interests[seedint], self.interests[seedint + 1])
                 self.seed_got_haves[piece] = 0       # reset this
                 self.seed_connections[connection] = piece
                 connection.upload.seed_have_list.append(piece)
                 return piece
     return -1       # something screwy; terminate connection
Пример #12
0
 def got_piece(self, index, begin, piece):
     length = len(piece)
     try:
         self.active_requests.remove((index, begin, length))
     except ValueError:
         self.downloader.discarded += length
         return False
     if self.downloader.endgamemode:
         self.downloader.all_requests.remove((index, begin, length))
     self.last = clock()
     self.last2 = clock()
     self.measure.update_rate(length)
     self.downloader.measurefunc(length)
     if not self.downloader.storage.piece_came_in(index, begin, piece, self.guard):
         self.downloader.piece_flunked(index)
         return False
     if self.downloader.storage.do_I_have(index):
         self.downloader.picker.complete(index)
     if self.downloader.endgamemode:
         for d in self.downloader.downloads:
             if d is not self:
               if d.interested:
                 if d.choked:
                     assert not d.active_requests
                     d.fix_download_endgame()
                 else:
                     try:
                         d.active_requests.remove((index, begin, length))
                     except ValueError:
                         continue
                     d.connection.send_cancel(index, begin, length)
                     d.fix_download_endgame()
               else:
                   assert not d.active_requests
     self._request_more()
     self.downloader.check_complete(index)
     return self.downloader.storage.do_I_have(index)
Пример #13
0
 def queue_limit(self):
     if not self.download_rate:
         return 10e10    # that's a big queue!
     t = clock()
     self.bytes_requested -= (t - self.last_time) * self.download_rate
     self.last_time = t
     if not self.requeueing and self.queued_out and self.bytes_requested < 0:
         self.requeueing = True
         q = self.queued_out.keys()
         shuffle(q)
         self.queued_out = {}
         for d in q:
             d._request_more()
         self.requeueing = False
     if -self.bytes_requested > 5*self.download_rate:
         self.bytes_requested = -5*self.download_rate
     return max(int(-self.bytes_requested/self.chunksize),0)
Пример #14
0
 def got_request(self, i, p, l):
     self.upload.got_request(i, p, l)
     if self.just_unchoked:
         self.connecter.ratelimiter.ping(clock() - self.just_unchoked)
         self.just_unchoked = 0
Пример #15
0
 def got_request(self, i, p, l):
     self.upload.got_request(i, p, l)
     if self.just_unchoked:
         self.connecter.ratelimiter.ping(clock() - self.just_unchoked)
         self.just_unchoked = 0
Пример #16
0
    def add_disconnected_seed(self, id):
#        if not self.disconnectedseeds.has_key(id):
#            self.picker.seed_seen_recently()
        self.disconnectedseeds[id]=clock()
Пример #17
0
 def got_unchoke(self):
     if self.choked:
         self.choked = False
         if self.interested:
             self._request_more(new_unchoke = True)
         self.last2 = clock()
Пример #18
0
 def send_interested(self):
     if not self.interested:
         self.interested = True
         self.connection.send_interested()
         if not self.choked:
             self.last2 = clock()