Repository navigation
feat(durable): read and stop executions with application credentials - #366
Conversation
Takes the hunks Kong/volcano-hosting#2364 adds to Hosting's public bundle: GET and POST stop on /durable-functions/{functionId}/executions/{executionId}, the start description, and the client_token description. Regenerates the internal client with bin/generate-openapi.
Adds Durable#get_from_application and Durable#stop_from_application. They call the application route with the credential #start uses, and send the execution's client token as X-Volcano-Client-Token when one is given. The owner-scoped #get, #list and #stop are unchanged; their docs no longer say an application credential can only start.
Splice the start, read and stop paths, the DurableClientToken parameter and the DurableExecution schema from Hosting main's public bundle (1ccff82a16), which #2364 merged into. A service key scoped to a list without `*` now needs the client token, only a key holding `*` reaches a pending execution, a throttled 503 carries Retry-After, and the start's 409 names `execution_name_held`. Regenerated with bin/generate-openapi.
…tops A service key reaches any execution only when it holds `*`; one scoped without it passes client_token: like an anon key. Pin that the token goes out with a service key, say a 503 stop may already have been sent, and use the error bodies the routes return (no code; 409 says the execution was never started).
AI review: no P0-P2 findingsAdds Not checked: The AI review read the diff, the code, and the PR's text; it ran no tests or builds and read nothing outside this repository.
Human review: not needed |
…ication reads A visibility refusal raises PermissionDeniedError rather than NotFoundError, and a service key scoped without * also needs functions.invoke.
A private function answers every credential but a service key with 404, so it raises NotFoundError. Only a missing functions.invoke or an anonymous key on an authenticated function raises PermissionDeniedError.
Change
A Ruby application can read and stop the durable executions it started, with the credential
startalready uses: the active session, then a service key, then the anon key. Before this,getandstopcalled only the owner routes, which need a platform token.GET /durable-functions/{functionId}/executions/{executionId}andPOST .../stop.client_token:goes out asX-Volcano-Client-Tokenwhen given, with any credential, and is omitted otherwise. A service key holding*reaches any execution; one scoped to a list without*needs the token, as an anon key does. It is checked like themessagesone: 1 to 128 printable ASCII characters.Volcano::Error::NotFoundError, which is also what a credential that cannot reach the execution gets. A 409 on stop (only a service key holding*reaches apendingexecution) raisesVolcano::Error::ConflictError. A 503 raisesVolcano::Error::ServerError; the docs say a throttled stop may already have been sent.retry_afterstaysnilon it: the shared transport readsRetry-Afteronly on 429, as the Python SDK does.get,listandstopare unchanged. Doc comments,docs/functions.mdand the README no longer say an application credential can only start.Server support shipped in Kong/volcano-hosting#2364 (merged as
29807384cf).Coordination branch:
skeever/durable-execution-data-plane.Contract snapshot
openapi/openapi.yamltakes only the durable sections #2364 changed, copied verbatim from Hosting main's public bundle (scripts/ci/openapi-bundle.shat1ccff82a16, byte-identical todocs/public/api-reference/openapi.yaml): the start, read and stop paths under/durable-functions/{functionId}/executions, theDurableClientTokenparameter, and theDurableExecutionschema. Those sections now parse equal to Hosting main's. That brings in what changed after the draft this PR first vendored: scoped service keys,*forpending, 503Retry-After, the start'sexecution_name_held409, and description text. The rest of Hosting's drift is left to the automated sync PR (#5). The client was regenerated withbin/generate-openapi,bin/check-openapipasses, and the pinned snapshot digest inspec/volcano_generation_spec.rbis updated.Verification
bundle exec rake qualityon 583625d (Ruby 3.4.10, Java 21):quality:audit: no vulnerabilities.quality:generated: generated boundary up to date.quality:lint: 417 files, no offenses.quality:types: RBS validate and both Steep targets, no errors.quality:spec: 2,197 examples, 0 failures. Line coverage 100% (5,907/5,907) and branch coverage 100% (1,645/1,645).quality:defects: all five injected defects detected.quality:package: gem built and smoke-tested in an isolated install.New specs cover:
AuthorizationandX-Volcano-Client-Token, through the real generated client (spec/volcano/durable_application_http_spec.rb), including the token sent with a service key;erroronly, nocode);Cross-language impact
Classification: public facade and SDK-facing wire contract.
tests/sdk-contract/requirements.mdhas no ID for application-route reads or stops (#2364 does not add one).tests/sdk-contract.docs/functions.mdand the README here; Hosting'sdocs/public/functions/durable-functions.mdshipped in #2364.Coordination
Companion PRs, all on
skeever/durable-execution-data-plane: Kong/volcano-sdk-js#357, Kong/volcano-sdk-python#422, #366.Merge order:
tests/sdk-contractscenarios for both routes.🤖 Generated with Claude Code