glib: Add a jitter to the interval by default when scheduling tasks

- When many tasks are scheduled at once, they will try to write to the database
at the same time. This happens prominently in develop mode when multiple
notifications are attempted to be shown.

- Also other resource contention may happen.

- Avoid this by adding or subtracting 5% to the provided task scheduling
interval time.

Tests:

- Print the interval times in the schedule() method and verify that the final
interval values are randomized and vary by only 5% from the provided interval.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2023-10-11 16:31:15 -07:00 committed by James Valleroy
parent 2bf4271e04
commit 16c556de45
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -4,6 +4,7 @@ Module to handle glib main loop and provide asynchronous utilities.
"""
import logging
import random
import threading
from plinth import dbus, network
@ -49,7 +50,8 @@ def _run():
logger.info('Glib main loop thread exited.')
def schedule(interval, method, data=None, in_thread=True, repeat=True):
def schedule(interval, method, data=None, in_thread=True, repeat=True,
add_jitter=True):
"""Schedule a recurring call to a method with fixed interval."""
def _runner():
@ -74,4 +76,10 @@ def schedule(interval, method, data=None, in_thread=True, repeat=True):
if cfg.develop and interval > 180:
interval = 180
if add_jitter:
# Add or subtract 5% random jitter to given interval to avoid many
# tasks running at exactly the same time (and competing for DB, disk,
# network, etc.).
interval *= 0.95 + (random.random() * 0.1)
glib.timeout_add(int(interval * 1000), _run_bare_or_thread, None)