openmedialibrary/oml/bandwidth.py

84 lines
2.1 KiB
Python

from time import time
import settings
import state
from websocket import trigger_event
import logging
logger = logging.getLogger(__name__)
class Bandwidth(object):
_last = {}
def __init__(self):
self._upload = Bucket('uploadRate')
self._download = Bucket('downloadRate')
self.update()
def update(self):
bandwidth = {
'up': self._upload.rate,
'down': self._download.rate
}
if bandwidth != self._last:
trigger_event('bandwidth', bandwidth)
self._last = bandwidth
state.main.call_later(1, self.update)
def download(self, amount):
return self._download.consume(amount)
def upload(self, amount):
return self._upload.consume(amount)
class Bucket(object):
_rate = 0
fill_rate = None
def __init__(self, pref):
self._pref = pref
self.update()
self.timestamp = time()
self.rate_timestamp = time()
def update(self):
rate = settings.preferences.get(self._pref, '')
if rate and rate.isdigit():
rate = max(float(rate) * 1024, 0)
if rate != self.fill_rate:
self.capacity = max(rate, 2*16*1024)
self._tokens = rate
self.fill_rate = rate
else:
self.fill_rate = None
def consume(self, tokens):
self.update()
if self.fill_rate is None:
self._rate += tokens
return True
if tokens <= self.tokens:
self._tokens -= tokens
self._rate += tokens
else:
return False
return True
def get_tokens(self):
now = time()
if self._tokens < self.capacity:
delta = self.fill_rate * (now - self.timestamp)
self._tokens = min(self.capacity, self._tokens + delta)
self.timestamp = now
return self._tokens
tokens = property(get_tokens)
def get_rate(self):
now = time()
rate = self._rate * (now - self.rate_timestamp)
self._rate = 0
self.rate_timestamp = now
return rate
rate = property(get_rate)