def __init__(self, external_add_task, config, set_option,
                       get_remote_endpoints, get_rates):
        if debug:
            if config['bandwidth_management']:
                print "bandwidth management is up."
            else:
                print "!@#!@#!@#!@#!@# bandwidth management is down."
        self.external_add_task = external_add_task
        self.config = config
        self.set_option = set_option
        self.get_rates = get_rates
        # Next few lines were added by David Harrison to use RTTMonitor2
        #if os.name == 'nt':
        #    icmp_impl = Win32Icmp()
        #elif os.name == 'posix':
        #    icmp_impl = UnixIcmp(external_add_task, config['xicmp_port'])
        def got_new_rtt(rtt):
            self.external_add_task(0, self._inspect_rates, rtt)
        #self.rttmonitor = RTTMonitor(got_new_rtt, icmp_impl)
        self.rttmonitor = RTTMonitor(got_new_rtt)
        self.nodefeeder = NodeFeeder(external_add_task=external_add_task,
                                     get_remote_endpoints=get_remote_endpoints,
                                     rttmonitor=self.rttmonitor)

        self.start_time = None

        self.max_samples = 10 # hmm...
        self.u = SizedList(self.max_samples)
        self.d = SizedList(self.max_samples)
        self.t = SizedList(self.max_samples * 10)
        self.ur = SizedList(self.max_samples)
        self.dr = SizedList(self.max_samples)

        self.current_std = 0.001        
        self.max_std = 0.001

        self.max_rates = {}
        self.max_rates["upload"] = 1.0
        self.max_rates["download"] = 1.0
        self.max_p = 1.0
        self.min_p = 2**500
        self.mid_p = ((self.max_p - self.min_p) / 2.0) + self.min_p
        self.old_p = None

        # I pulled these numbers out of my ass.

        if stats:
            tmp_dir = platform.get_temp_dir()
            timestr = "%d_%d_%d_%d_%d" % time.localtime()[1:6]
            stats_dir = os.path.join( tmp_dir, "bittorrent%s_%d" %
                (timestr, os.getpid()) )
            os.mkdir(stats_dir)
            if debug: print "BandwidthManager: stats_dir = %s" % stats_dir
            rate_vs_time = os.path.join( stats_dir, "rate_vs_time.plotdata" )
            self.rfp = open( rate_vs_time, "w" )
            delay_vs_time = os.path.join( stats_dir, "delay_vs_time.plotdata" )
            self.dfp = open( delay_vs_time, "w" )
            sdev_vs_time = os.path.join( stats_dir, 
                "stddev_vs_time.plotdata" )
            self.sdevfp = open( sdev_vs_time, "w" )
Beispiel #2
0
class HistoryCollector(object):

    def __init__(self, span, interval):
        self.max_len = int(span / (interval / 1000))
        self.interval = interval
        self.upload_data = SizedList(self.max_len)
        self.download_data = SizedList(self.max_len)
        self.max_upload_rate = 0
        self.max_download_rate = 0
        self.variance = 0
        self.max_variance = 1
        self.viewer = None

    def update(self, upload_rate, download_rate,
               max_upload_rate, max_download_rate,
               variance, max_variance):
#         if (len(self.data) == 0):
#             self.data.append(random.random() * 500.0)
#         else:
#             self.data.append(self.data[-1] * ((random.random() * 0.04) + 0.98))

        self.upload_data.append(upload_rate or 0)
        self.download_data.append(download_rate or 0)
        self.max_upload_rate = max_upload_rate
        self.max_download_rate = max_download_rate
        self.variance = variance
        self.max_variance = max_variance
        if self.viewer:
            self.viewer()
Beispiel #3
0
class HistoryCollector(object):
    def __init__(self, span, interval):
        self.max_len = int(span / (interval / 1000))
        self.interval = interval
        self.upload_data = SizedList(self.max_len)
        self.download_data = SizedList(self.max_len)
        self.max_upload_rate = 0
        self.max_download_rate = 0
        self.variance = 0
        self.max_variance = 1
        self.viewer = None

    def update(self, upload_rate, download_rate, max_upload_rate,
               max_download_rate, variance, max_variance):
        #         if (len(self.data) == 0):
        #             self.data.append(random.random() * 500.0)
        #         else:
        #             self.data.append(self.data[-1] * ((random.random() * 0.04) + 0.98))

        self.upload_data.append(upload_rate or 0)
        self.download_data.append(download_rate or 0)
        self.max_upload_rate = max_upload_rate
        self.max_download_rate = max_download_rate
        self.variance = variance
        self.max_variance = max_variance
        if self.viewer:
            self.viewer()
Beispiel #4
0
 def __init__(self, span, interval):
     self.max_len = int(span / (interval / 1000))
     self.interval = interval
     self.upload_data = SizedList(self.max_len)
     self.download_data = SizedList(self.max_len)
     self.max_upload_rate = 0
     self.max_download_rate = 0
     self.variance = 0
     self.max_variance = 1
     self.viewer = None
Beispiel #5
0
 def __init__(self, span, interval):
     self.max_len = int(span / (interval / 1000))
     self.interval = interval
     self.upload_data = SizedList(self.max_len)
     self.download_data = SizedList(self.max_len)
     self.max_upload_rate = 0
     self.max_download_rate = 0
     self.variance = 0
     self.max_variance = 1
     self.viewer = None
class BandwidthManager(object):
    
    def __init__(self, external_add_task, config, set_option,
                       get_remote_endpoints, get_rates):
        if debug:
            if config['bandwidth_management']:
                print "bandwidth management is up."
            else:
                print "!@#!@#!@#!@#!@# bandwidth management is down."
        self.external_add_task = external_add_task
        self.config = config
        self.set_option = set_option
        self.get_rates = get_rates
        # Next few lines were added by David Harrison to use RTTMonitor2
        #if os.name == 'nt':
        #    icmp_impl = Win32Icmp()
        #elif os.name == 'posix':
        #    icmp_impl = UnixIcmp(external_add_task, config['xicmp_port'])
        def got_new_rtt(rtt):
            self.external_add_task(0, self._inspect_rates, rtt)
        #self.rttmonitor = RTTMonitor(got_new_rtt, icmp_impl)
        self.rttmonitor = RTTMonitor(got_new_rtt)
        self.nodefeeder = NodeFeeder(external_add_task=external_add_task,
                                     get_remote_endpoints=get_remote_endpoints,
                                     rttmonitor=self.rttmonitor)

        self.start_time = None

        self.max_samples = 10 # hmm...
        self.u = SizedList(self.max_samples)
        self.d = SizedList(self.max_samples)
        self.t = SizedList(self.max_samples * 10)
        self.ur = SizedList(self.max_samples)
        self.dr = SizedList(self.max_samples)

        self.current_std = 0.001        
        self.max_std = 0.001

        self.max_rates = {}
        self.max_rates["upload"] = 1.0
        self.max_rates["download"] = 1.0
        self.max_p = 1.0
        self.min_p = 2**500
        self.mid_p = ((self.max_p - self.min_p) / 2.0) + self.min_p
        self.old_p = None

        # I pulled these numbers out of my ass.

        if stats:
            tmp_dir = platform.get_temp_dir()
            timestr = "%d_%d_%d_%d_%d" % time.localtime()[1:6]
            stats_dir = os.path.join( tmp_dir, "bittorrent%s_%d" %
                (timestr, os.getpid()) )
            os.mkdir(stats_dir)
            if debug: print "BandwidthManager: stats_dir = %s" % stats_dir
            rate_vs_time = os.path.join( stats_dir, "rate_vs_time.plotdata" )
            self.rfp = open( rate_vs_time, "w" )
            delay_vs_time = os.path.join( stats_dir, "delay_vs_time.plotdata" )
            self.dfp = open( delay_vs_time, "w" )
            sdev_vs_time = os.path.join( stats_dir, 
                "stddev_vs_time.plotdata" )
            self.sdevfp = open( sdev_vs_time, "w" )

    def _method_1(self, type, t, c, old_c, rate):
        # This concept is:
        # if the correlation is high and the latency is high
        # then lower the bandwidth limit.
        # otherwise, raise it.

        if ((c > 0.96) and (t > 100)): 
            rate /= 2.0
            if debug:
                print type, "down to", rate
        else:
            rate += 500 # hmm
            if debug:
                print type, "up to", rate
        return rate
    
    def _method_2(self, type, t, c, old_c, rate):
        # This concept is:
        # if the correlation is low and the latency is high, lower the limit
        # otherwise raise it

        if ((c < 0.60) and (t > 100)): 
            rate /= 2.0
            if debug: 
                print type, "down to", rate
        else:
            rate += 500 # hmm
            if debug:
                print type, "up to", rate
        return rate

    def _method_vegasish(self, type, t, c, old_c, rate):

        middle_rtt = ((self.rttmonitor.get_min_rtt() +
                       self.rttmonitor.get_max_rtt()) / 2.0)
        if t > middle_rtt:
            rate *= 1.0/8.0
            if debug:
                print type, "down to", rate
        else:
            rate += 1000 # hmm
            if debug:
                print type, "up to", rate
        return rate            

    def _method_vegas_greg(self, type, t, c, old_c, rate):

        middle_rtt = ((self.rttmonitor.get_min_rtt() +
                       self.rttmonitor.get_max_rtt()) / 2.0)
        if t > middle_rtt and c < 0.5:
            rate *= 1.0/8.0
            if debug:
                print type, "down to", rate
        else:
            rate += 1000 # hmm
            if debug:
                print type, "up to", rate
        return rate            

    def _method_ratio(self, type, t, p, min_p, max_p, rate):
        ratio = p / max_p
        if debug:
            print "RATIO", ratio
        if ratio < 0.5:
            rate = ratio * self.max_rates[type]
            if debug:
                print type.upper(), "SET to", rate
        else:
            rate += rate * (ratio/10.0) # hmm
            if debug:
                print type.upper(), "UP to", rate
                
        return max(rate, 1000)


    def _method_stddev(self, type, std, max_std, rate):
        if std > (max_std * 0.80): # FUDGE
            rate *= 0.80 # FUDGE
            if debug:
                print type.upper(), "DOWN to", rate
        else:
            rate += 1000 # FUDGE
            if debug:
                print type.upper(), "UP to", rate

        return max(rate, 1000) # FUDGE
    
    
    def _affect_rate(self, type, std, max_std, rate, set):
        rate = self._method_stddev(type, std, max_std, rate)

        rock_bottom = False
        if rate <= 4096:
            if debug:
                print "Rock bottom"
            rock_bottom = True
            rate = 4096
    
        set(int(rate))

        if stats:
            print "BandwidthManager._affect_rate(%f)" % rate
            self.rfp.write( "%d %d" % (bttime(),int(rate)) )
            self.sdevfp.write( "%d %f" % (bttime(), std ) )

        return rock_bottom
        

    def _inspect_rates(self, t = None):

        if t == None:
            t = self.rttmonitor.get_current_rtt()

        if t == None:
            # this makes timeouts reduce the maximum std deviation
            self.max_std *= 0.80 # FUDGE
            return

        if self.start_time == None:
            self.start_time = bttime()

        if debug:
            print "BandwidthManager._inspect_rates rtt: %d" % t
        if stats:
            self.dfp.write( "%d %d" % (bttime(),t) )

        def set_if_enabled(option, value):
            if not self.config['bandwidth_management']:
                return
            if debug:
                print "Setting %s to: %s" % (option, value)
            self.set_option(option, value)

        # TODO: slow start should be smarter than this
        if self.start_time + 20 > bttime():
            if debug:
                print 'SLOW START', fp(self.start_time + 20), fp(bttime())
            set_if_enabled('max_upload_rate', 10000000)
            set_if_enabled('max_download_rate', 10000000)

        if t < 3:
            # I simply don't believe you. Go away.
            return

        tup = self.get_rates()
        if tup == None:
            return
        u, d = tup
        #print "udt", u, d, t
        #print "uprate, downrate=", u, d

        self.u.append(u)
        self.d.append(d)
        self.t.append(t)
        self.ur.append(self.config['max_upload_rate'])
        self.dr.append(self.config['max_download_rate'])

        #s = time.time()
        #cu = correlation(self.u, self.t)
        #cd = correlation(self.d, self.t)
        #cur = correlation(self.u, self.ur)
        #cdr = correlation(self.d, self.dr)
        #e = time.time()

        self.current_std = standard_deviation(self.t)
        
        pu = ratio_sum_lists(self.u, self.t)
        pd = ratio_sum_lists(self.d, self.t)
        if len(self.u) > 2:
            lp = [ x/y for x, y in itertools.izip(self.u, self.t) ]
            min_pu = min(*lp)
            max_pu = max(*lp)
        else:
            min_pu = u / t
            max_pu = u / t
        pu = u / t

        self.max_rates["upload"] = max(max(self.u), self.max_rates["upload"])
        self.max_rates["download"] = max(max(self.d), self.max_rates["download"])

        if debug:
            print 'urate:', fp(u), 'umax:', self.config['max_upload_rate'], \
                  'maxstd:', fp(self.max_std), 'std:', fp(self.current_std), \
                  'pu:', fp(pu), 'pd:', fp(pd)
        
        rb = self._affect_rate("upload", self.current_std, self.max_std,
                               self.config['max_upload_rate'],
                               lambda r : set_if_enabled('max_upload_rate', r))
        # don't adjust download rate, it's not nearly correlated enough
##        if rb:
##            v = int(self.config['max_download_rate'] * 0.90) # FUDGE
##            v = max(v, 2000) # FUDGE
##            set_if_enabled('max_download_rate', v) 
##        else:
##            v = int(self.config['max_download_rate'] + 6000) # FUDGE
##            set_if_enabled('max_download_rate', v) 
##        if debug:
##            print "DOWNLOAD SET to", v
            
        #self._affect_rate("download", t, cd, self.last_cd, pd,
        #                  self.config['max_download_rate'],
        #                  lambda r : self.set_option('max_download_rate', r))

        self.max_std = max(self.max_std, self.current_std)
Beispiel #7
0
    def __init__(self, external_add_task, config, set_option,
                 get_remote_endpoints, get_rates):
        if debug:
            if config['bandwidth_management']:
                print "bandwidth management is up."
            else:
                print "!@#!@#!@#!@#!@# bandwidth management is down."
        self.external_add_task = external_add_task
        self.config = config
        self.set_option = set_option
        self.get_rates = get_rates

        # Next few lines were added by David Harrison to use RTTMonitor2
        #if os.name == 'nt':
        #    icmp_impl = Win32Icmp()
        #elif os.name == 'posix':
        #    icmp_impl = UnixIcmp(external_add_task, config['xicmp_port'])
        def got_new_rtt(rtt):
            self.external_add_task(0, self._inspect_rates, rtt)

        #self.rttmonitor = RTTMonitor(got_new_rtt, icmp_impl)
        self.rttmonitor = RTTMonitor(got_new_rtt)
        self.nodefeeder = NodeFeeder(external_add_task=external_add_task,
                                     get_remote_endpoints=get_remote_endpoints,
                                     rttmonitor=self.rttmonitor)

        self.start_time = None

        self.max_samples = 10  # hmm...
        self.u = SizedList(self.max_samples)
        self.d = SizedList(self.max_samples)
        self.t = SizedList(self.max_samples * 2)
        self.ur = SizedList(self.max_samples)
        self.dr = SizedList(self.max_samples)

        self.current_std = 0.001
        self.max_std = 0.001
        self.last_max = bttime()

        self.max_rates = {}
        self.max_rates["upload"] = 1.0
        self.max_rates["download"] = 1.0
        self.max_p = 1.0
        self.min_p = 2**500
        self.mid_p = ((self.max_p - self.min_p) / 2.0) + self.min_p
        self.old_p = None

        # I pulled these numbers out of my ass.

        if stats:
            tmp_dir = platform.get_temp_dir()
            timestr = "%d_%d_%d_%d_%d" % time.localtime()[1:6]
            stats_dir = os.path.join(
                tmp_dir, "bittorrent%s_%d" % (timestr, os.getpid()))
            os.mkdir(stats_dir)
            if debug: print "BandwidthManager: stats_dir = %s" % stats_dir
            rate_vs_time = os.path.join(stats_dir, "rate_vs_time.plotdata")
            self.rfp = open(rate_vs_time, "w")
            delay_vs_time = os.path.join(stats_dir, "delay_vs_time.plotdata")
            self.dfp = open(delay_vs_time, "w")
            sdev_vs_time = os.path.join(stats_dir, "stddev_vs_time.plotdata")
            self.sdevfp = open(sdev_vs_time, "w")
Beispiel #8
0
class BandwidthManager(object):
    def __init__(self, external_add_task, config, set_option,
                 get_remote_endpoints, get_rates):
        if debug:
            if config['bandwidth_management']:
                print "bandwidth management is up."
            else:
                print "!@#!@#!@#!@#!@# bandwidth management is down."
        self.external_add_task = external_add_task
        self.config = config
        self.set_option = set_option
        self.get_rates = get_rates

        # Next few lines were added by David Harrison to use RTTMonitor2
        #if os.name == 'nt':
        #    icmp_impl = Win32Icmp()
        #elif os.name == 'posix':
        #    icmp_impl = UnixIcmp(external_add_task, config['xicmp_port'])
        def got_new_rtt(rtt):
            self.external_add_task(0, self._inspect_rates, rtt)

        #self.rttmonitor = RTTMonitor(got_new_rtt, icmp_impl)
        self.rttmonitor = RTTMonitor(got_new_rtt)
        self.nodefeeder = NodeFeeder(external_add_task=external_add_task,
                                     get_remote_endpoints=get_remote_endpoints,
                                     rttmonitor=self.rttmonitor)

        self.start_time = None

        self.max_samples = 10  # hmm...
        self.u = SizedList(self.max_samples)
        self.d = SizedList(self.max_samples)
        self.t = SizedList(self.max_samples * 2)
        self.ur = SizedList(self.max_samples)
        self.dr = SizedList(self.max_samples)

        self.current_std = 0.001
        self.max_std = 0.001
        self.last_max = bttime()

        self.max_rates = {}
        self.max_rates["upload"] = 1.0
        self.max_rates["download"] = 1.0
        self.max_p = 1.0
        self.min_p = 2**500
        self.mid_p = ((self.max_p - self.min_p) / 2.0) + self.min_p
        self.old_p = None

        # I pulled these numbers out of my ass.

        if stats:
            tmp_dir = platform.get_temp_dir()
            timestr = "%d_%d_%d_%d_%d" % time.localtime()[1:6]
            stats_dir = os.path.join(
                tmp_dir, "bittorrent%s_%d" % (timestr, os.getpid()))
            os.mkdir(stats_dir)
            if debug: print "BandwidthManager: stats_dir = %s" % stats_dir
            rate_vs_time = os.path.join(stats_dir, "rate_vs_time.plotdata")
            self.rfp = open(rate_vs_time, "w")
            delay_vs_time = os.path.join(stats_dir, "delay_vs_time.plotdata")
            self.dfp = open(delay_vs_time, "w")
            sdev_vs_time = os.path.join(stats_dir, "stddev_vs_time.plotdata")
            self.sdevfp = open(sdev_vs_time, "w")

    def _method_1(self, type, t, c, old_c, rate):
        # This concept is:
        # if the correlation is high and the latency is high
        # then lower the bandwidth limit.
        # otherwise, raise it.

        if ((c > 0.96) and (t > 100)):
            rate /= 2.0
            if debug:
                print type, "down to", rate
        else:
            rate += 500  # hmm
            if debug:
                print type, "up to", rate
        return rate

    def _method_2(self, type, t, c, old_c, rate):
        # This concept is:
        # if the correlation is low and the latency is high, lower the limit
        # otherwise raise it

        if ((c < 0.60) and (t > 100)):
            rate /= 2.0
            if debug:
                print type, "down to", rate
        else:
            rate += 500  # hmm
            if debug:
                print type, "up to", rate
        return rate

    def _method_vegasish(self, type, t, c, old_c, rate):

        middle_rtt = (
            (self.rttmonitor.get_min_rtt() + self.rttmonitor.get_max_rtt()) /
            2.0)
        if t > middle_rtt:
            rate *= 1.0 / 8.0
            if debug:
                print type, "down to", rate
        else:
            rate += 1000  # hmm
            if debug:
                print type, "up to", rate
        return rate

    def _method_vegas_greg(self, type, t, c, old_c, rate):

        middle_rtt = (
            (self.rttmonitor.get_min_rtt() + self.rttmonitor.get_max_rtt()) /
            2.0)
        if t > middle_rtt and c < 0.5:
            rate *= 1.0 / 8.0
            if debug:
                print type, "down to", rate
        else:
            rate += 1000  # hmm
            if debug:
                print type, "up to", rate
        return rate

    def _method_ratio(self, type, t, p, min_p, max_p, rate):
        ratio = p / max_p
        if debug:
            print "RATIO", ratio
        if ratio < 0.5:
            rate = ratio * self.max_rates[type]
            if debug:
                print type.upper(), "SET to", rate
        else:
            rate += rate * (ratio / 10.0)  # hmm
            if debug:
                print type.upper(), "UP to", rate

        return max(rate, 1000)

    def _method_stddev(self, type, std, max_std, rate):
        top = 0.80  # FUDGE
        if std > (max_std * top):
            center = 1.0 + top - ((1.0 - top) * 0.5)
            s = min(std / max(0.0001, max_std), center)
            s = center - s
            rate *= s
            if debug:
                print type.upper(), "DOWN *", s, "to", rate
        else:
            s = 1000.0  # FUDGE
            s *= min(max_std / max(0.0001, std), 4) / 4.0
            s = int(s)
            rate += s
            if debug:
                print type.upper(), "UP +", s, "to", rate

        return max(rate, 1000)  # FUDGE

    def _affect_rate(self, type, std, max_std, rate, set):
        rate = self._method_stddev(type, std, max_std, rate)

        rock_bottom = False
        if rate <= 4096:
            if debug:
                print "Rock bottom"
            rock_bottom = True
            rate = 4096

        set(int(rate))

        if stats:
            print "BandwidthManager._affect_rate(%f)" % rate
            self.rfp.write("%d %d" % (bttime(), int(rate)))
            self.sdevfp.write("%d %f" % (bttime(), std))

        return rock_bottom

    def _inspect_rates(self, t=None):

        if t == None:
            t = self.rttmonitor.get_current_rtt()

        if t == None:
            # this makes timeouts reduce the maximum std deviation
            self.max_std *= 0.80  # FUDGE
            return

        if self.start_time == None:
            self.start_time = bttime()

        if debug:
            print "BandwidthManager._inspect_rates rtt: %d" % t
        if stats:
            self.dfp.write("%d %d" % (bttime(), t))

        def set_if_enabled(option, value):
            if not self.config['bandwidth_management']:
                return
            if debug:
                print "Setting %s to: %s" % (option, value)
            self.set_option(option, value)

        # TODO: slow start should be smarter than this
        if self.start_time + 20 > bttime():
            if debug:
                print 'SLOW START', fp(self.start_time + 20), fp(bttime())
            set_if_enabled('max_upload_rate', 10000000)
            set_if_enabled('max_download_rate', 10000000)

        if t < 3:
            # I simply don't believe you. Go away.
            return

        tup = self.get_rates()
        if tup == None:
            return
        u, d = tup
        #print "udt", u, d, t
        #print "uprate, downrate=", u, d

        self.u.append(u)
        self.d.append(d)
        self.t.append(t)
        self.ur.append(self.config['max_upload_rate'])
        self.dr.append(self.config['max_download_rate'])

        #s = time.time()
        #cu = correlation(self.u, self.t)
        #cd = correlation(self.d, self.t)
        #cur = correlation(self.u, self.ur)
        #cdr = correlation(self.d, self.dr)
        #e = time.time()

        self.current_std = standard_deviation(self.t)

        pu = ratio_sum_lists(self.u, self.t)
        pd = ratio_sum_lists(self.d, self.t)
        if len(self.u) > 2:
            lp = [x / y for x, y in itertools.izip(self.u, self.t)]
            min_pu = min(*lp)
            max_pu = max(*lp)
        else:
            min_pu = u / t
            max_pu = u / t
        pu = u / t

        self.max_rates["upload"] = max(max(self.u), self.max_rates["upload"])
        self.max_rates["download"] = max(max(self.d),
                                         self.max_rates["download"])

        if debug:
            print 'urate:', fp(u), 'umax:', self.config['max_upload_rate'], \
                  'maxstd:', fp(self.max_std), 'std:', fp(self.current_std), \
                  'pu:', fp(pu), 'pd:', fp(pd)

        rb = self._affect_rate("upload", self.current_std, self.max_std,
                               self.config['max_upload_rate'],
                               lambda r: set_if_enabled('max_upload_rate', r))
        # don't adjust download rate, it's not nearly correlated enough
        ##        if rb:
        ##            v = int(self.config['max_download_rate'] * 0.90) # FUDGE
        ##            v = max(v, 2000) # FUDGE
        ##            set_if_enabled('max_download_rate', v)
        ##        else:
        ##            v = int(self.config['max_download_rate'] + 6000) # FUDGE
        ##            set_if_enabled('max_download_rate', v)
        ##        if debug:
        ##            print "DOWNLOAD SET to", v

        #self._affect_rate("download", t, cd, self.last_cd, pd,
        #                  self.config['max_download_rate'],
        #                  lambda r : self.set_option('max_download_rate', r))

        if self.current_std > self.max_std:
            self.max_std = self.current_std
            self.last_max = bttime()
        elif bttime() - self.last_max > 10:
            # decay old maximums, to recover from flakey connections
            self.max_std *= 0.90  # FUDGE
            self.last_max = bttime()