[Repo Assist] feat: add CancellationToken support to OpenApiClientProvider generated methods (closes #212)#336
Conversation
…d methods (closes #212) - Add CallAsync overload with CancellationToken to ProvidedApiClientBase - Thread CancellationToken from generated methods through to HttpClient.SendAsync - Each generated method gains an optional cancellationToken parameter (defaults to CancellationToken.None) - Backward-compatible: existing call sites without CT continue to work unchanged - Add unit tests: success with CancellationToken.None, cancellation propagation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot finish or and fix the build |
|
@sergey-tihon I've opened a new pull request, #337, to work on those changes. Once the pull request is ready, I'll request review from you. |
…overloads (#337) * Initial plan * Fix: revert global.json and address CancellationToken build failures Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 * fix: use method overloading for CancellationToken support instead of optional struct parameter Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds CancellationToken plumbing to the OpenAPI v3 generated client methods by extending the runtime ProvidedApiClientBase.CallAsync API and updating the v3 operation compiler, with tests added around the new runtime overload.
Changes:
- Add
CallAsyncoverload that accepts aCancellationTokenand forwards it toHttpClient.SendAsync. - Generate v3 client method overloads that accept a
CancellationTokenand pass it through toCallAsync. - Extend runtime tests to validate success and already-cancelled token behavior; update stub handler to honor cancellation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| tests/SwaggerProvider.Tests/RuntimeHelpersTests.fs | Adds coverage for CallAsync cancellation forwarding and updates stub handler to throw on cancellation. |
| src/SwaggerProvider.Runtime/ProvidedApiClientBase.fs | Introduces CallAsync overload with CancellationToken and delegates existing overload to CancellationToken.None. |
| src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs | Generates additional operation method overloads and wires CT through to runtime CallAsync. |
| global.json | Changes pinned .NET SDK version used by the repo. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot add typeprovider tests that actually call TP generated methods with cancellation token |
|
@sergey-tihon I've opened a new pull request, #338, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@sergey-tihon I've opened a new pull request, #339, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@sergey-tihon I've opened a new pull request, #340, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@sergey-tihon I've opened a new pull request, #341, to work on those changes. Once the pull request is ready, I'll request review from you. |
…ation (#339) * Initial plan * fix: generate unique CT parameter name to avoid collision with OpenAPI params named 'cancellationToken' Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/7d588ec7-c4df-4a6c-89f8-9c13c2472d29 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
…rationCompiler (#341) * Initial plan * fix: insert CT between required and optional params; generate unique CT name Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/b0c519de-0186-40ca-8174-42ed67a5316a * fix: add explicit restore + --no-restore to BuildTests to fix NETSDK1005 Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/565d6633-576d-4587-b924-a29b0ea53c2c --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
|
✅ Repo Assist completed successfully! |
Replace hand-coded recursive findUniqueName function with the existing UniqueNameGenerator utility (already used in DefinitionCompiler and for method name deduplication in OperationCompiler). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Commit pushed:
|
|
✅ Repo Assist completed successfully! |
…structor Allows callers to pre-seed the generator with names that are already taken, so MakeUnique will never return any of those names without a numeric suffix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Commit pushed:
|
|
✅ Repo Assist completed successfully! |
…tional CancellationToken - Remove no-CT CallAsync overload from ProvidedApiClientBase; keep only the version with explicit CancellationToken (quotation code always supplies it) - Remove double-compilation in OperationCompiler: one method per operation with optional cancellationToken (null default = default(CancellationToken).None) - Update RuntimeHelpersTests to pass CancellationToken.None explicitly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Commit pushed:
|
- Use List.map instead of List.collect since compileOperation returns a single method - Clean up comments in OperationCompiler - Add test for calling generated method without CancellationToken (default token) - Add test for async (PreferAsync=true) generated method without CancellationToken
…eamAsync via RuntimeHelpers Add readContentAsString and readContentAsStream wrappers to RuntimeHelpers with #if NET5_0_OR_GREATER guards, enabling CancellationToken propagation in generated quotation code that must compile against netstandard2.0. Also add explicit CancellationToken integration tests and conditional CT support in ProvidedApiClientBase error path.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Adds optional
CancellationTokensupport to all methods generated byOpenApiClientProvider(v3), closing #212.Before: Generated methods had no way to cancel in-flight HTTP requests.
After: Every generated method has an optional
cancellationTokenparameter (defaulting toCancellationToken.None). Existing code continues to work unchanged.Design Decisions
Single method per operation, no overloads — The ProvidedTypes SDK does not support method overloads (
GetMethodImplthrows atProvidedTypes.fs:1632). Each operation compiles to exactly one method with an optional CT parameter appended last.null default for struct parameter —
ProvidedParameter(name, typeof<CancellationToken>, false, null)emits valid IL. The runtime interpretsnullasdefault(CancellationToken)=CancellationToken.None.SetConstantonly supports primitives/strings/null, so a real struct default is not possible.CT positioned after all required + optional params — Preserves backward compatibility with existing positional argument calls in user code and tests.
UniqueNameGenerator with occupiedNames — Avoids name collisions if an API already has a parameter named
cancellationToken.PreferAsync=true works automatically — The implementation always uses
task { }internally and passes CT toHttpClient.SendAsync. WhenasAsync=true, results are wrapped viaAsync.AwaitTask, which cooperatively propagates cancellation.Changes
Core (4 files)
src/SwaggerProvider.DesignTime/v3/OperationCompiler.fsCallAsyncsrc/SwaggerProvider.Runtime/ProvidedApiClientBase.fsCallAsyncwith 4 args (request, errorCodes, errorDescriptions, cancellationToken); passes CT toHttpClient.SendAsyncsrc/SwaggerProvider.DesignTime/Utils.fsUniqueNameGeneratoraccepts optionaloccupiedNamesparameterbuild.fsxdotnet restorebeforedotnet build --no-restoreto fix TFM asset file raceTests (4 files)
tests/SwaggerProvider.ProviderTests/v3/Swashbuckle.CancellationToken.Tests.fsPreferAsync=true)tests/SwaggerProvider.Tests/RuntimeHelpersTests.fsCallAsyncwith CT; existing tests updated to 4-arg signaturetests/SwaggerProvider.Tests/UtilsTests.fsUniqueNameGeneratoroccupied names featuretests/SwaggerProvider.ProviderTests/SwaggerProvider.ProviderTests.fsprojInfrastructure (2 files)
global.json.github/Test Results
Full
./build.shpipeline passes (Status: Ok):Scope
Only v3
OpenApiClientProvideris modified. The v2SwaggerClientProvideris left unchanged and could be updated in a follow-up.