Optimised resource performance over varied network topologies

This commit is contained in:
Mark Qvist 2022-06-09 19:29:33 +02:00
parent 02968baa76
commit 2c1b3a0e5b
1 changed files with 42 additions and 9 deletions

View File

@ -42,19 +42,39 @@ class Resource:
:param callback: An optional *callable* with the signature *callback(resource)*. Will be called when the resource transfer concludes. :param callback: An optional *callable* with the signature *callback(resource)*. Will be called when the resource transfer concludes.
:param progress_callback: An optional *callable* with the signature *callback(resource)*. Will be called whenever the resource transfer progress is updated. :param progress_callback: An optional *callable* with the signature *callback(resource)*. Will be called whenever the resource transfer progress is updated.
""" """
WINDOW_FLEXIBILITY = 4
# The initial window size at beginning of transfer
WINDOW = 4
# Absolute minimum window size during transfer
WINDOW_MIN = 1 WINDOW_MIN = 1
# The maximum window size for transfers on slow links
WINDOW_MAX_SLOW = 10 WINDOW_MAX_SLOW = 10
# The maximum window size for transfers on fast links
WINDOW_MAX_FAST = 76 WINDOW_MAX_FAST = 76
WINDOW_MAX = 76 # For calculating maps and guard segments, this
WINDOW = WINDOW_MAX # must be set to the global maximum window.
# TODO: Reset WINDOW_MAX = WINDOW_MAX_FAST
# WINDOW = 4
RATE_SLOW = 1000 # If the fast rate is sustained for this many request
RATE_FAST = 10*1000*1000 # rounds, the fast link window size will be allowed.
FAST_RATE_THRESHOLD = WINDOW_MAX_SLOW - WINDOW - 2
# If the RTT rate is higher than this value,
# the max window size for fast links will be used.
# The default is 3 Mbps (the value is stored in
# bytes per second).
RATE_FAST = (3*1000*1000)/8
# The minimum allowed flexibility of the window size.
# The difference between window_max and window_min
# will never be smaller than this value.
WINDOW_FLEXIBILITY = 4
# Number of bytes in a map hash
MAPHASH_LEN = 4 MAPHASH_LEN = 4
SDU = RNS.Packet.MDU SDU = RNS.Packet.MDU
RANDOM_HASH_SIZE = 4 RANDOM_HASH_SIZE = 4
@ -129,7 +149,7 @@ class Resource:
resource.outstanding_parts = 0 resource.outstanding_parts = 0
resource.parts = [None] * resource.total_parts resource.parts = [None] * resource.total_parts
resource.window = Resource.WINDOW resource.window = Resource.WINDOW
resource.window_max = Resource.WINDOW_MAX resource.window_max = Resource.WINDOW_MAX_SLOW
resource.window_min = Resource.WINDOW_MIN resource.window_min = Resource.WINDOW_MIN
resource.window_flexibility = Resource.WINDOW_FLEXIBILITY resource.window_flexibility = Resource.WINDOW_FLEXIBILITY
resource.last_activity = time.time() resource.last_activity = time.time()
@ -228,6 +248,8 @@ class Resource:
self.__watchdog_job_id = 0 self.__watchdog_job_id = 0
self.__progress_callback = progress_callback self.__progress_callback = progress_callback
self.rtt = None self.rtt = None
self.req_resp_rtt_rate = 0
self.fast_rate_rounds = 0
self.request_id = request_id self.request_id = request_id
self.is_response = is_response self.is_response = is_response
@ -594,7 +616,7 @@ class Resource:
if self.req_resp == None: if self.req_resp == None:
self.req_resp = self.last_activity self.req_resp = self.last_activity
rtt = self.req_resp-self.req_sent rtt = self.req_resp-self.req_sent
self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR_AFTER_RTT self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR_AFTER_RTT
if self.rtt == None: if self.rtt == None:
self.rtt = self.link.rtt self.rtt = self.link.rtt
@ -604,6 +626,16 @@ class Resource:
elif rtt > self.rtt: elif rtt > self.rtt:
self.rtt = min(self.rtt + self.rtt*0.05, rtt) self.rtt = min(self.rtt + self.rtt*0.05, rtt)
if rtt > 0:
req_resp_cost = len(packet.raw)+self.req_sent_bytes
self.req_resp_rtt_rate = req_resp_cost / rtt
if self.req_resp_rtt_rate > Resource.RATE_FAST and self.fast_rate_rounds < Resource.FAST_RATE_THRESHOLD:
self.fast_rate_rounds += 1
if self.fast_rate_rounds == Resource.FAST_RATE_THRESHOLD:
self.window_max = Resource.WINDOW_MAX_FAST
if not self.status == Resource.FAILED: if not self.status == Resource.FAILED:
self.status = Resource.TRANSFERRING self.status = Resource.TRANSFERRING
part_data = packet.data part_data = packet.data
@ -695,6 +727,7 @@ class Resource:
request_packet.send() request_packet.send()
self.last_activity = time.time() self.last_activity = time.time()
self.req_sent = self.last_activity self.req_sent = self.last_activity
self.req_sent_bytes = len(request_packet.raw)
self.req_resp = None self.req_resp = None
except Exception as e: except Exception as e:
RNS.log("Could not send resource request packet, cancelling resource", RNS.LOG_DEBUG) RNS.log("Could not send resource request packet, cancelling resource", RNS.LOG_DEBUG)