Re #580 - jitter delay

This commit is contained in:
dgtlmoon
2022-06-11 19:24:43 +02:00
parent 327cc4af34
commit c8b60c2489
6 changed files with 39 additions and 18 deletions
+28 -11
View File
@@ -1274,8 +1274,11 @@ def notification_runner():
# Thread runner to check every minute, look for new watches to feed into the Queue.
def ticker_thread_check_time_launch_checks():
import random
from changedetectionio import update_worker
import logging
recheck_time_minimum_seconds = int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 60))
print("System env MINIMUM_SECONDS_RECHECK_TIME", recheck_time_minimum_seconds)
# Spin up Workers that do the fetching
# Can be overriden by ENV or use the default settings
@@ -1308,14 +1311,13 @@ def ticker_thread_check_time_launch_checks():
while update_q.qsize() >= 2000:
time.sleep(1)
# Check for watches outside of the time threshold to put in the thread queue.
now = time.time()
recheck_time_minimum_seconds = int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 60))
recheck_time_system_seconds = datastore.threshold_seconds
recheck_time_system_seconds = int(datastore.threshold_seconds)
for uuid in watch_uuid_list:
# Check for watches outside of the time threshold to put in the thread queue.
now = int(time.time())
watch = datastore.data['watching'].get(uuid)
if not watch:
logging.error("Watch: {} no longer present.".format(uuid))
@@ -1333,13 +1335,28 @@ def ticker_thread_check_time_launch_checks():
else:
threshold -= recheck_time_system_seconds
# Yeah, put it in the queue, it's more than time
if watch['last_checked'] <= max(threshold, recheck_time_minimum_seconds):
if not uuid in running_uuids and uuid not in update_q.queue:
update_q.put(uuid)
# #580 - Jitter plus/minus amount of time to make the check seem more random to the server
jitter = datastore.data['settings']['requests'].get('jitter_seconds', 0)
if jitter > 0:
if watch.jitter_seconds == 0:
watch.jitter_seconds = random.uniform(-abs(jitter), jitter)
# Wait a few seconds before checking the list again
time.sleep(3)
# `threshold` set to "now" minus calculated seconds before it should be rechecked
# threshold = 1555555555-10 and so watch['last_checked'] = 1555555444
# anyone 'last_checked' less than "1555555555-10" should be rechecked
if watch['last_checked'] <= min(threshold - watch.jitter_seconds, threshold - recheck_time_minimum_seconds):
if not uuid in running_uuids and uuid not in update_q.queue:
print("Watch UUID {} last checked at {} queued at {} jitter {:0.2f}, {}since".format(uuid,
watch['last_checked'],
str(int(time.time())),
watch.jitter_seconds,
int(time.time())-watch['last_checked']))
update_q.put(uuid)
watch.jitter_seconds = 0
# Wait before checking the list again
time.sleep(1)
# Should be low so we can break this out in testing
app.config.exit.wait(1)
+1 -1
View File
@@ -363,7 +363,7 @@ class watchForm(commonSettingsForm):
class globalSettingsRequestForm(Form):
time_between_check = FormField(TimeBetweenCheckForm)
proxy = RadioField('Proxy')
jitter_seconds = IntegerField('Random jitter ± delay time for checks' , render_kw={"style": "width: 5em;"}, validators=[validators.NumberRange(min=0, message="Should contain zero or more seconds")])
# datastore.data['settings']['application']..
class globalSettingsApplicationForm(commonSettingsForm):
+1
View File
@@ -23,6 +23,7 @@ class model(dict):
'requests': {
'timeout': 15, # Default 15 seconds
'time_between_check': {'weeks': None, 'days': None, 'hours': 3, 'minutes': None, 'seconds': None},
'jitter_seconds': 0,
'workers': 10, # Number of threads, lower is better for slow connections
'proxy': None # Preferred proxy connection
},
+3 -4
View File
@@ -13,7 +13,6 @@ from changedetectionio.notification import (
class model(dict):
__newest_history_key = None
__history_n=0
__base_config = {
'url': None,
'tag': None,
@@ -48,7 +47,8 @@ class model(dict):
'time_between_check': {'weeks': None, 'days': None, 'hours': None, 'minutes': None, 'seconds': None},
'webdriver_delay': None
}
jitter_seconds = 0
mtable = {'seconds': 1, 'minutes': 60, 'hours': 3600, 'days': 86400, 'weeks': 86400 * 7}
def __init__(self, *arg, **kw):
import uuid
self.update(self.__base_config)
@@ -157,8 +157,7 @@ class model(dict):
def threshold_seconds(self):
seconds = 0
mtable = {'seconds': 1, 'minutes': 60, 'hours': 3600, 'days': 86400, 'weeks': 86400 * 7}
for m, n in mtable.items():
for m, n in self.mtable.items():
x = self.get('time_between_check', {}).get(m, None)
if x:
seconds += x * n
+1 -2
View File
@@ -159,12 +159,11 @@ class ChangeDetectionStore:
def threshold_seconds(self):
seconds = 0
mtable = {'seconds': 1, 'minutes': 60, 'hours': 3600, 'days': 86400, 'weeks': 86400 * 7}
minimum_seconds_recheck_time = int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 60))
for m, n in mtable.items():
x = self.__data['settings']['requests']['time_between_check'].get(m)
if x:
seconds += x * n
return max(seconds, minimum_seconds_recheck_time)
return seconds
@property
def has_unviewed(self):
@@ -32,6 +32,11 @@
{{ render_field(form.requests.form.time_between_check, class="time-check-widget") }}
<span class="pure-form-message-inline">Default time for all watches, when the watch does not have a specific time setting.</span>
</div>
<div class="pure-control-group">
{{ render_field(form.requests.form.jitter_seconds, class="jitter_seconds") }}
<span class="pure-form-message-inline">Example - 3 seconds random jitter could trigger up to 3 seconds earlier or up to 3 seconds later</span>
</div>
<div class="pure-control-group">
{% if not hide_remove_pass %}
{% if current_user.is_authenticated %}