Makes test_execution_limit_group_throttle_wait pass

Makes test_jobs_decorator.py::test_execution_limit_group_throttle_wait
pass even when using group locks.
This commit is contained in:
Stefan Agner 2025-07-14 19:03:42 +02:00
parent 351de4d9a3
commit c71daefd7f
No known key found for this signature in database
GPG Key ID: AE01353D1E44747D
2 changed files with 7 additions and 19 deletions

View File

@ -111,7 +111,7 @@ class Job(CoreSysAttributes):
JobExecutionLimit.GROUP_WAIT: (JobConcurrency.GROUP_QUEUE, None),
JobExecutionLimit.GROUP_THROTTLE: (None, JobThrottle.GROUP_THROTTLE),
JobExecutionLimit.GROUP_THROTTLE_WAIT: (
JobConcurrency.QUEUE, # Seems a bit counter intuitive, but GROUP_QUEUE deadlocks tests/jobs/test_job_decorator.py::test_execution_limit_group_throttle_wait
JobConcurrency.GROUP_QUEUE,
JobThrottle.GROUP_THROTTLE,
),
JobExecutionLimit.GROUP_THROTTLE_RATE_LIMIT: (
@ -148,19 +148,6 @@ class Job(CoreSysAttributes):
)
self._rate_limited_calls = {}
if self.throttle in (
JobThrottle.GROUP_THROTTLE,
JobThrottle.GROUP_RATE_LIMIT,
) and self.concurrency in (
JobConcurrency.GROUP_REJECT,
JobConcurrency.GROUP_QUEUE,
):
# We cannot release group locks when Job is not running (e.g. throttled)
# which makes these combinations impossible to use currently.
raise RuntimeError(
f"Job {self.name} is using group throttling ({self.throttle}) with group concurrency ({self.concurrency}), which is not allowed!"
)
@property
def throttle_max_calls(self) -> int:
"""Return max calls for throttle."""
@ -505,7 +492,7 @@ class Job(CoreSysAttributes):
JobConcurrency.GROUP_REJECT,
JobConcurrency.GROUP_QUEUE,
):
if job_group and job_group.has_lock:
if job_group:
job_group.release()
async def _handle_concurrency_control(

View File

@ -3,7 +3,7 @@
from asyncio import Lock
from ..coresys import CoreSys, CoreSysAttributes
from ..exceptions import JobException, JobGroupExecutionLimitExceeded
from ..exceptions import JobGroupExecutionLimitExceeded
from . import SupervisorJob
@ -70,10 +70,11 @@ class JobGroup(CoreSysAttributes):
self._active_job = job
def release(self) -> None:
"""Release the lock for the group or return it to parent."""
if not self.has_lock:
raise JobException("Cannot release as caller does not own lock")
"""Release the lock for the group or return it to parent.
It is the callers responsibility to ensure that the lock is only released
when the lock is actually being held.
"""
if self._parent_jobs:
self._active_job = self._parent_jobs.pop()
else: