Skip to content

Commit 96ff1e9

Browse files
committed
add min_time_interval and min_value_interval to progress update methods
1 parent f1fda50 commit 96ff1e9

File tree

2 files changed

+102
-20
lines changed

2 files changed

+102
-20
lines changed

taskbadger/sdk.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -327,18 +327,33 @@ def update_status(self, status: StatusEnum):
327327
"""Update the task status"""
328328
self.update(status=status)
329329

330-
def increment_progress(self, amount: int):
331-
"""Increment the task progress.
330+
def increment_progress(self, amount: int, min_value_interval: int = None, min_time_interval: int = None):
331+
"""Increment the task progress by adding the specified amount to the current value.
332332
If the task value is not set it will be set to `amount`.
333+
334+
Arguments:
335+
amount: The amount to increment the task value by.
336+
min_value_interval: The minimum change in value required to trigger an update.
337+
min_time_interval: The minimum interval between updates in seconds.
333338
"""
334339
value = self._task.value
335340
value_norm = value if value is not UNSET and value is not None else 0
336341
new_amount = value_norm + amount
337-
self.update(value=new_amount)
342+
self.update_progress(new_amount, min_value_interval, min_time_interval)
338343

339-
def update_progress(self, value: int):
340-
"""Update task progress."""
341-
self.update(value=value)
344+
def update_progress(self, value: int, min_value_interval: int = None, min_time_interval: int = None):
345+
"""Update task progress.
346+
347+
Arguments:
348+
value: The new value to set.
349+
min_value_interval: The minimum change in value required to trigger an update.
350+
min_time_interval: The minimum interval between updates in seconds.
351+
"""
352+
skip_check = not (min_value_interval or min_time_interval)
353+
time_check = min_time_interval and self._check_update_time_interval(min_time_interval)
354+
value_check = min_value_interval and self._check_update_value_interval(value, min_value_interval)
355+
if skip_check or time_check or value_check:
356+
self.update(value=value)
342357

343358
def set_value_max(self, value_max: int):
344359
"""Set the `value_max`."""
@@ -393,22 +408,16 @@ def tag(self, tags: dict[str, str]):
393408
"""Add tags to the task."""
394409
self.update(tags=tags)
395410

396-
def ping(self, min_ping_interval=None):
411+
def ping(self, min_time_interval=None):
397412
"""Update the task without changing any values. This can be used in conjunction
398413
with 'stale_timeout' to indicate that the task is still running.
399414
400415
Arguments:
401-
min_ping_interval: The minimum interval between pings in seconds. If set this will only
402-
update the task if the last update was more than `min_ping_interval` seconds ago.
416+
min_time_interval: The minimum interval between pings in seconds. If set this will only
417+
update the task if the last update was more than `min_time_interval` seconds ago.
403418
"""
404-
if min_ping_interval and self._task.updated:
405-
# tzinfo should always be set but for the sake of safety we check
406-
tz = None if self._task.updated.tzinfo is None else datetime.UTC
407-
now = datetime.datetime.now(tz)
408-
time_since = now - self._task.updated
409-
if time_since.total_seconds() < min_ping_interval:
410-
return
411-
self.update()
419+
if self._check_update_time_interval(min_time_interval):
420+
self.update()
412421

413422
@property
414423
def tags(self):
@@ -423,6 +432,20 @@ def safe_update(self, **kwargs):
423432
except Exception as e:
424433
log.warning("Error updating task '%s': %s", self._task.id, e)
425434

435+
def _check_update_time_interval(self, min_time_interval: int = None):
436+
if min_time_interval and self._task.updated:
437+
# tzinfo should always be set but for the sake of safety we check
438+
tz = None if self._task.updated.tzinfo is None else datetime.UTC
439+
now = datetime.datetime.now(tz)
440+
time_since = now - self._task.updated
441+
return time_since.total_seconds() >= min_time_interval
442+
return True
443+
444+
def _check_update_value_interval(self, new_value, min_value_interval: int = None):
445+
if min_value_interval and self._task.value:
446+
return new_value - self._task.value >= min_value_interval
447+
return True
448+
426449

427450
def _none_to_unset(value):
428451
return UNSET if value is None else value

tests/test_sdk.py

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,77 @@ def test_ping(settings, patched_update):
159159

160160
updated_at = task.updated
161161
patched_update.return_value = Response(HTTPStatus.OK, b"", {}, task_for_test())
162-
task.ping(min_ping_interval=1)
162+
task.ping(min_time_interval=1)
163163
assert len(patched_update.call_args_list) == 0
164164

165165
task.ping()
166166
_verify_update(settings, patched_update)
167167
assert task.updated > updated_at
168168

169-
task.ping(min_ping_interval=1)
169+
task.ping(min_time_interval=1)
170170
assert len(patched_update.call_args_list) == 1
171171

172172
task._task.updated = task._task.updated - datetime.timedelta(seconds=1)
173-
task.ping(min_ping_interval=1)
173+
task.ping(min_time_interval=1)
174+
assert len(patched_update.call_args_list) == 2
175+
176+
177+
def test_update_progress_min_time_interval(settings, patched_update):
178+
task = Task(task_for_test(value=1))
179+
180+
updated_at = task.updated
181+
patched_update.return_value = Response(HTTPStatus.OK, b"", {}, task_for_test())
182+
task.update_progress(2, min_time_interval=1)
183+
assert len(patched_update.call_args_list) == 0
184+
185+
task.update_progress(2)
186+
_verify_update(settings, patched_update, value=2)
187+
assert task.updated > updated_at
188+
189+
task.update_progress(3, min_time_interval=1)
190+
assert len(patched_update.call_args_list) == 1
191+
192+
task._task.updated = task._task.updated - datetime.timedelta(seconds=1)
193+
task.update_progress(3, min_time_interval=1)
194+
assert len(patched_update.call_args_list) == 2
195+
196+
197+
def test_update_progress_min_value_interval(settings, patched_update):
198+
task = Task(task_for_test(value=1))
199+
200+
patched_update.return_value = Response(HTTPStatus.OK, b"", {}, task_for_test(value=4))
201+
task.update_progress(4, min_value_interval=5)
202+
assert len(patched_update.call_args_list) == 0
203+
204+
task.update_progress(4)
205+
_verify_update(settings, patched_update, value=4)
206+
207+
task.update_progress(8, min_value_interval=5)
208+
assert len(patched_update.call_args_list) == 1
209+
210+
task.update_progress(9, min_value_interval=5)
211+
assert len(patched_update.call_args_list) == 2
212+
213+
214+
def test_update_progress_min_interval_both(settings, patched_update):
215+
task = Task(task_for_test(value=1))
216+
217+
patched_update.return_value = Response(HTTPStatus.OK, b"", {}, task_for_test(value=4))
218+
# neither checks pass
219+
task.update_progress(4, min_time_interval=1, min_value_interval=5)
220+
assert len(patched_update.call_args_list) == 0
221+
222+
# value check passes
223+
task.update_progress(6, min_time_interval=1, min_value_interval=5)
224+
_verify_update(settings, patched_update, value=6)
225+
226+
# neither checks pass
227+
task.update_progress(8, min_time_interval=1, min_value_interval=5)
228+
assert len(patched_update.call_args_list) == 1
229+
230+
# time check passes
231+
task._task.updated = task._task.updated - datetime.timedelta(seconds=1)
232+
task.update_progress(6, min_time_interval=1, min_value_interval=5)
174233
assert len(patched_update.call_args_list) == 2
175234

176235

0 commit comments

Comments
 (0)