Skip to content

Commit 88d8e3f

Browse files
Kowserclaude
andcommitted
Drop _legacy_scheduler_verbs dialect cache — stateless PUT-then-GET
pause/resume: try PUT; on 405 retry via GET. No per-instance memoization. Contract test updated to pin the stateless behavior; docs adjusted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 265c51d commit 88d8e3f

4 files changed

Lines changed: 10 additions & 23 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- `@worker_task` workers are now picklable, making the decorator path work with the `spawn`/`forkserver` start methods (fixes `TypeError: cannot pickle '_thread.lock' object` and `PicklingError: it's not the same object as ...`; issues #264, #271): `Worker.api_client` is created lazily in the worker process, runtime state (locks, pending async tasks, background loop) is excluded from pickling and rebuilt in the child, and decorated functions are pickled as importable references resolved in the child
3131
- `TaskHandler.start_processes()` no longer hangs the interpreter when a worker fails to start (e.g., unpicklable state under `spawn`); it now cleans up already-started subprocesses and raises with actionable guidance
3232
- Worker processes killed by a signal now log a diagnostic hint (signal number, `PYTHONFAULTHANDLER=1` guidance) instead of restarting silently
33-
- Per-schedule pause/resume now work on both Conductor server families: the client sends `PUT` (the OSS Conductor dialect — the spec-generated `GET` failed there) and transparently falls back to `GET` on a 405 for Orkes servers, caching the working dialect per client instance
33+
- Per-schedule pause/resume now work on both Conductor server families: the client sends `PUT` (the OSS Conductor dialect — the spec-generated `GET` failed there) and transparently falls back to `GET` on a 405 for Orkes servers

docs/SCHEDULE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ Operations for controlling schedule execution state.
3737

3838
> **Verb compatibility:** OSS Conductor maps per-schedule pause/resume as `PUT`;
3939
> Orkes Conductor servers map them as `GET`. The client sends `PUT` first and
40-
> transparently falls back to `GET` on a 405, remembering the working dialect for
41-
> the rest of the client's lifetime — both server families work without configuration.
42-
> The optional `reason` parameter on `pause_schedule` is stored by OSS servers only.
40+
> transparently falls back to `GET` on a 405 — both server families work without
41+
> configuration. The optional `reason` parameter on `pause_schedule` is stored by
42+
> OSS servers only.
4343
4444
## Schedule Lifecycle Helpers
4545

src/conductor/client/orkes/orkes_scheduler_client.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
class OrkesSchedulerClient(OrkesBaseClient, SchedulerClient):
1616
def __init__(self, configuration: Configuration):
1717
super(OrkesSchedulerClient, self).__init__(configuration)
18-
# Per-schedule pause/resume verbs differ by server family: OSS Conductor maps them
19-
# PUT-only, Orkes Conductor GET-only. We send PUT first and remember a 405 so
20-
# subsequent calls go straight to the legacy GET dialect.
21-
self._legacy_scheduler_verbs = False
2218

2319
def save_schedule(self, save_schedule_request: SaveScheduleRequest):
2420
self.schedulerResourceApi.save_schedule(save_schedule_request)
@@ -57,9 +53,8 @@ def delete_schedule(self, name: str):
5753
self.schedulerResourceApi.delete_schedule(name)
5854

5955
def pause_schedule(self, name: str, reason: Optional[str] = None):
60-
if self._legacy_scheduler_verbs:
61-
self._pause_resume_via_get(name, "pause", reason)
62-
return
56+
# Per-schedule pause/resume verbs differ by server family: OSS Conductor maps
57+
# them PUT-only, Orkes Conductor GET-only. Try PUT; on 405 retry via GET.
6358
try:
6459
if reason is None:
6560
self.schedulerResourceApi.pause_schedule(name)
@@ -68,22 +63,17 @@ def pause_schedule(self, name: str, reason: Optional[str] = None):
6863
except ApiException as e:
6964
if e.status != 405:
7065
raise
71-
self._legacy_scheduler_verbs = True
7266
self._pause_resume_via_get(name, "pause", reason)
7367

7468
def pause_all_schedules(self):
7569
self.schedulerResourceApi.pause_all_schedules()
7670

7771
def resume_schedule(self, name: str):
78-
if self._legacy_scheduler_verbs:
79-
self._pause_resume_via_get(name, "resume")
80-
return
8172
try:
8273
self.schedulerResourceApi.resume_schedule(name)
8374
except ApiException as e:
8475
if e.status != 405:
8576
raise
86-
self._legacy_scheduler_verbs = True
8777
self._pause_resume_via_get(name, "resume")
8878

8979
def _pause_resume_via_get(self, name: str, action: str, reason: Optional[str] = None):

tests/unit/orkes/test_scheduler_resource_contract.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,16 @@ def test_405_falls_back_to_get(self):
124124
assert args[2] == {"name": "sched-1"}
125125
assert ("reason", "maintenance") in args[3]
126126

127-
def test_405_result_is_cached_for_subsequent_calls(self):
127+
def test_fallback_is_stateless(self):
128128
client = _client_with_mocks()
129129
client.schedulerResourceApi.pause_schedule.side_effect = ApiException(
130130
status=405, reason="Method Not Allowed"
131131
)
132132
client.pause_schedule("sched-1")
133133
client.pause_schedule("sched-2")
134-
client.resume_schedule("sched-1")
135-
# PUT attempted exactly once; everything after the 405 goes straight to GET.
136-
assert client.schedulerResourceApi.pause_schedule.call_count == 1
137-
client.schedulerResourceApi.resume_schedule.assert_not_called()
138-
assert client.api_client.call_api.call_count == 3
134+
# No dialect memoization: every call attempts PUT first, then falls back.
135+
assert client.schedulerResourceApi.pause_schedule.call_count == 2
136+
assert client.api_client.call_api.call_count == 2
139137

140138
def test_404_propagates_without_fallback(self):
141139
client = _client_with_mocks()
@@ -145,7 +143,6 @@ def test_404_propagates_without_fallback(self):
145143
with pytest.raises(ApiException):
146144
client.pause_schedule("missing")
147145
client.api_client.call_api.assert_not_called()
148-
assert client._legacy_scheduler_verbs is False
149146

150147
def test_resume_405_falls_back_to_get(self):
151148
client = _client_with_mocks()

0 commit comments

Comments
 (0)