Peter Surda
6d2a75bfc9
- send buffer to send multiple commands in one TCP packet - recv/send operation size now based on bandwith limit - send queue limited to 100 entries - buffer getdata commands to fill send queue, instead of waiting for the data packet to arrive first (i.e. allow getdata to work asynchronously)
82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
import math
|
|
import threading
|
|
import time
|
|
|
|
from configparser import BMConfigParser
|
|
from singleton import Singleton
|
|
import state
|
|
|
|
class Throttle(object):
|
|
minChunkSize = 4096
|
|
maxChunkSize = 131072
|
|
|
|
def __init__(self, limit=0):
|
|
self.limit = limit
|
|
self.speed = 0
|
|
self.chunkSize = Throttle.maxChunkSize
|
|
self.txTime = int(time.time())
|
|
self.txLen = 0
|
|
self.total = 0
|
|
self.timer = threading.Event()
|
|
self.lock = threading.RLock()
|
|
self.resetChunkSize()
|
|
|
|
def recalculate(self):
|
|
with self.lock:
|
|
now = int(time.time())
|
|
if now > self.txTime:
|
|
self.speed = self.txLen / (now - self.txTime)
|
|
self.txLen -= self.limit * (now - self.txTime)
|
|
self.txTime = now
|
|
if self.txLen < 0 or self.limit == 0:
|
|
self.txLen = 0
|
|
|
|
def wait(self, dataLen):
|
|
with self.lock:
|
|
self.txLen += dataLen
|
|
self.total += dataLen
|
|
while state.shutdown == 0:
|
|
self.recalculate()
|
|
if self.limit == 0:
|
|
break
|
|
if self.txLen < self.limit:
|
|
break
|
|
self.timer.wait(0.2)
|
|
|
|
def getSpeed(self):
|
|
self.recalculate()
|
|
return self.speed
|
|
|
|
def resetChunkSize(self):
|
|
with self.lock:
|
|
# power of two smaller or equal to speed limit
|
|
try:
|
|
self.chunkSize = int(math.pow(2, int(math.log(self.limit,2))))
|
|
except ValueError:
|
|
self.chunkSize = Throttle.maxChunkSize
|
|
# range check
|
|
if self.chunkSize < Throttle.minChunkSize:
|
|
self.chunkSize = Throttle.minChunkSize
|
|
elif self.chunkSize > Throttle.maxChunkSize:
|
|
self.chunkSize = Throttle.maxChunkSize
|
|
|
|
@Singleton
|
|
class SendThrottle(Throttle):
|
|
def __init__(self):
|
|
Throttle.__init__(self, BMConfigParser().safeGetInt('bitmessagesettings', 'maxuploadrate')*1024)
|
|
|
|
def resetLimit(self):
|
|
with self.lock:
|
|
self.limit = BMConfigParser().safeGetInt('bitmessagesettings', 'maxuploadrate')*1024
|
|
Throttle.resetChunkSize()
|
|
|
|
@Singleton
|
|
class ReceiveThrottle(Throttle):
|
|
def __init__(self):
|
|
Throttle.__init__(self, BMConfigParser().safeGetInt('bitmessagesettings', 'maxdownloadrate')*1024)
|
|
|
|
def resetLimit(self):
|
|
with self.lock:
|
|
self.limit = BMConfigParser().safeGetInt('bitmessagesettings', 'maxdownloadrate')*1024
|
|
Throttle.resetChunkSize()
|