Skip to content

Commit d6d463b

Browse files
Expose server dispatch admission budgets in Python SDK task-queue visibility
Expose dispatch admission fields in Python SDK
1 parent 4a6bc0c commit d6d463b

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ for queue in queues.task_queues:
171171
print(queue.name, workflow_admission.status if workflow_admission else "unknown")
172172
```
173173

174+
The workflow and activity admission objects expose both queue-level and
175+
namespace-level server budgets, including active lease caps and per-minute
176+
dispatch-rate limits, so automation can detect whether local worker slots,
177+
queue caps, or namespace caps are constraining throughput.
178+
174179
## Replay captured histories
175180

176181
Use `Replayer` to debug a captured history without connecting to a live server:

src/durable_workflow/client.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ class TaskQueueTaskAdmission:
118118
server_max_active_leases_per_queue: int | None = None
119119
server_active_lease_count: int | None = None
120120
server_remaining_active_lease_capacity: int | None = None
121+
server_max_active_leases_per_namespace: int | None = None
122+
server_namespace_active_lease_count: int | None = None
123+
server_remaining_namespace_active_lease_capacity: int | None = None
124+
server_max_dispatches_per_minute: int | None = None
125+
server_dispatch_count_this_minute: int | None = None
126+
server_remaining_dispatch_capacity: int | None = None
127+
server_max_dispatches_per_minute_per_namespace: int | None = None
128+
server_namespace_dispatch_count_this_minute: int | None = None
129+
server_remaining_namespace_dispatch_capacity: int | None = None
121130
server_lock_required: bool | None = None
122131
server_lock_supported: bool | None = None
123132

@@ -137,6 +146,19 @@ def from_dict(cls, data: dict[str, Any] | None) -> TaskQueueTaskAdmission | None
137146
server_max_active_leases_per_queue=data.get("server_max_active_leases_per_queue"),
138147
server_active_lease_count=data.get("server_active_lease_count"),
139148
server_remaining_active_lease_capacity=data.get("server_remaining_active_lease_capacity"),
149+
server_max_active_leases_per_namespace=data.get("server_max_active_leases_per_namespace"),
150+
server_namespace_active_lease_count=data.get("server_namespace_active_lease_count"),
151+
server_remaining_namespace_active_lease_capacity=data.get(
152+
"server_remaining_namespace_active_lease_capacity"
153+
),
154+
server_max_dispatches_per_minute=data.get("server_max_dispatches_per_minute"),
155+
server_dispatch_count_this_minute=data.get("server_dispatch_count_this_minute"),
156+
server_remaining_dispatch_capacity=data.get("server_remaining_dispatch_capacity"),
157+
server_max_dispatches_per_minute_per_namespace=data.get(
158+
"server_max_dispatches_per_minute_per_namespace"
159+
),
160+
server_namespace_dispatch_count_this_minute=data.get("server_namespace_dispatch_count_this_minute"),
161+
server_remaining_namespace_dispatch_capacity=data.get("server_remaining_namespace_dispatch_capacity"),
140162
server_lock_required=data.get("server_lock_required"),
141163
server_lock_supported=data.get("server_lock_supported"),
142164
)

tests/test_client.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,15 @@ async def test_list_task_queues_parses_admission(self, client: Client) -> None:
383383
"server_max_active_leases_per_queue": 1,
384384
"server_active_lease_count": 1,
385385
"server_remaining_active_lease_capacity": 0,
386+
"server_max_active_leases_per_namespace": 8,
387+
"server_namespace_active_lease_count": 7,
388+
"server_remaining_namespace_active_lease_capacity": 1,
389+
"server_max_dispatches_per_minute": 60,
390+
"server_dispatch_count_this_minute": 60,
391+
"server_remaining_dispatch_capacity": 0,
392+
"server_max_dispatches_per_minute_per_namespace": 240,
393+
"server_namespace_dispatch_count_this_minute": 200,
394+
"server_remaining_namespace_dispatch_capacity": 40,
386395
"server_lock_required": True,
387396
"server_lock_supported": True,
388397
},
@@ -412,6 +421,15 @@ async def test_list_task_queues_parses_admission(self, client: Client) -> None:
412421
assert queue.admission.workflow_tasks is not None
413422
assert queue.admission.workflow_tasks.status == "throttled"
414423
assert queue.admission.workflow_tasks.server_remaining_active_lease_capacity == 0
424+
assert queue.admission.workflow_tasks.server_max_active_leases_per_namespace == 8
425+
assert queue.admission.workflow_tasks.server_namespace_active_lease_count == 7
426+
assert queue.admission.workflow_tasks.server_remaining_namespace_active_lease_capacity == 1
427+
assert queue.admission.workflow_tasks.server_max_dispatches_per_minute == 60
428+
assert queue.admission.workflow_tasks.server_dispatch_count_this_minute == 60
429+
assert queue.admission.workflow_tasks.server_remaining_dispatch_capacity == 0
430+
assert queue.admission.workflow_tasks.server_max_dispatches_per_minute_per_namespace == 240
431+
assert queue.admission.workflow_tasks.server_namespace_dispatch_count_this_minute == 200
432+
assert queue.admission.workflow_tasks.server_remaining_namespace_dispatch_capacity == 40
415433
assert queue.admission.activity_tasks is not None
416434
assert queue.admission.activity_tasks.configured_slot_count == 5
417435
assert queue.admission.query_tasks is not None

0 commit comments

Comments
 (0)