[Swift6][Client] Make Swift 6 generator thread safe#23191
[Swift6][Client] Make Swift 6 generator thread safe#231914brunu wants to merge 7 commits intoOpenAPITools:masterfrom
Conversation
There was a problem hiding this comment.
4 issues found across 94 files
Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:33">
P2: Changing `dateFormatter` does not invalidate cached default JSON encoder/decoder, so later encodes/decodes can keep using an outdated date strategy.</violation>
</file>
<file name="samples/client/petstore/swift6/oneOf/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/oneOf/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift:33">
P2: Updating `dateFormatter` does not invalidate cached default JSON encoder/decoder, so encode/decode can continue using an outdated date strategy.</violation>
</file>
<file name="samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:33">
P2: Updating `dateFormatter` does not invalidate cached default coder instances, so later encode/decode calls can continue using an outdated formatter.</violation>
</file>
<file name="samples/client/petstore/swift6/asyncAwaitLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/asyncAwaitLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:33">
P2: Updating `dateFormatter` does not invalidate cached default JSON coders, so encode/decode may keep using an outdated date format.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
...t/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
...ent/petstore/swift6/oneOf/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
...petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
.../petstore/swift6/asyncAwaitLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
2 issues found across 14 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/swift6/rxswiftLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/rxswiftLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift:48">
P1: Mutating shared `JSONDecoder`/`JSONEncoder` strategies in place can race with concurrent encode/decode calls. Recreate default coders when `dateFormatter` changes instead of updating existing instances.</violation>
</file>
<file name="samples/client/petstore/swift6/resultLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/resultLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift:30">
P1: Updating date strategies by mutating shared default decoder/encoder instances can race with callers using previously returned decoder/encoder references. Recreate defaults when the formatter changes instead of mutating existing shared instances.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
...ore/swift6/rxswiftLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
...tore/swift6/resultLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
6 issues found across 14 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/swift6/default/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/default/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:25">
P2: Rebuilding default coders by creating new `JSONDecoder`/`JSONEncoder` instances drops any existing caller customizations when `dateFormatter` is updated.</violation>
</file>
<file name="samples/client/petstore/swift6/promisekitLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/promisekitLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift:25">
P2: Rebuilding new JSONDecoder/JSONEncoder instances on date formatter changes drops existing decoder/encoder customizations made through the exposed default instances.</violation>
</file>
<file name="samples/client/petstore/swift6/urlsessionLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/urlsessionLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:25">
P2: Rebuilding decoder/encoder instances on `dateFormatter` updates resets previously configured `jsonDecoder`/`jsonEncoder` options (e.g., key strategies), causing silent behavior regressions.</violation>
</file>
<file name="samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:35">
P2: Recreating default JSON coders in `rebuildDefaultCoders()` drops any prior caller customization on the default encoder/decoder when `dateFormatter` changes.</violation>
</file>
<file name="samples/client/petstore/swift6/objcCompatible/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/objcCompatible/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:35">
P2: Rebuilding default coders creates new JSONEncoder/JSONDecoder instances and drops existing coder configuration when `dateFormatter` changes.</violation>
</file>
<file name="samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1" location="samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:25">
P2: Rebuilding new JSONDecoder/JSONEncoder instances in `rebuildDefaultCoders()` resets previously customized default coder settings when `dateFormatter` changes.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
...les/client/petstore/swift6/default/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
.../swift6/promisekitLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
.../petstore/swift6/urlsessionLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
...t/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Show resolved
Hide resolved
...ent/petstore/swift6/objcCompatible/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
...petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
26 issues found across 14 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/swift6/resultLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: Encoding is now performed outside the mutex, so concurrent configuration changes can race with active encoding.</violation>
<violation number="2">
P1: Decoding is no longer protected by the mutex, allowing races with concurrent coder reconfiguration (for example `dateFormatter` updates).</violation>
</file>
<file name="samples/client/petstore/swift6/combineLibrary/Sources/CombineLibrary/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` now executes outside synchronization, allowing races with concurrent encoder/date formatter reconfiguration.</violation>
<violation number="2">
P1: `decode` now runs outside the mutex, so coder use can race with concurrent configuration updates.</violation>
</file>
<file name="samples/client/petstore/swift6/objcCompatible/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` uses a shared `JSONEncoder` outside the mutex, allowing concurrent encode/reconfigure races.</violation>
<violation number="2">
P1: `decode` uses a shared `JSONDecoder` outside the mutex, reintroducing a race between decoding and formatter-driven decoder reconfiguration.</violation>
</file>
<file name="samples/client/petstore/swift6/oneOf/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: Encode now uses the shared `JSONEncoder` outside mutex protection, which can race with concurrent state mutation.</violation>
<violation number="2">
P1: Decode now runs outside the mutex while using a shared `JSONDecoder`, reintroducing a data race and breaking the thread-safety goal.</violation>
</file>
<file name="samples/client/petstore/swift6/promisekitLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` is executed outside the mutex, so the shared default encoder can be mutated concurrently during serialization.</violation>
<violation number="2">
P1: `decode` no longer runs under the mutex, allowing concurrent mutation/use of the shared default decoder.</violation>
</file>
<file name="samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: Encoding now runs on the shared JSONEncoder outside the mutex, allowing races with concurrent state mutations.</violation>
<violation number="2">
P1: Decoding now uses the shared JSONDecoder outside the mutex, reintroducing a data race with concurrent formatter/decoder updates.</violation>
</file>
<file name="samples/client/petstore/swift6/rxswiftLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` now uses a shared `JSONEncoder` outside the mutex, so concurrent formatter updates can race with encoding.</violation>
<violation number="2">
P1: `decode` now uses a shared `JSONDecoder` outside the mutex, which can race with concurrent `dateFormatter` updates that mutate decoder strategy.</violation>
</file>
<file name="samples/client/petstore/swift6/asyncAwaitLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: Encoding now runs outside the mutex, which can race with concurrent encoder configuration updates.</violation>
<violation number="2">
P1: Decoding now runs outside the mutex, allowing unsynchronized concurrent access to shared decoder state.</violation>
</file>
<file name="samples/client/petstore/swift6/validation/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` now performs encoding outside the mutex, so shared mutable `JSONEncoder` state can be accessed concurrently.</violation>
<violation number="2">
P1: `decode` now performs decoding outside the mutex, allowing concurrent access to a shared mutable `JSONDecoder` and reintroducing data-race risk.</violation>
</file>
<file name="samples/client/petstore/swift6/combineDeferredLibrary/PetstoreClient/Classes/OpenAPIs/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: Encoding now runs outside the mutex, reintroducing a race on shared encoder state.</violation>
<violation number="2">
P1: Decoding now executes outside the mutex, allowing concurrent access to shared decoder state.</violation>
</file>
<file name="samples/client/petstore/swift6/default/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `decode` now executes outside the mutex, allowing concurrent use of shared decoder state and reintroducing a thread-safety race.</violation>
<violation number="2" location="samples/client/petstore/swift6/default/Sources/PetstoreClient/Infrastructure/CodableHelper.swift:30">
P1: `rebuildDefaultCoders` mutates shared encoder/decoder instances in place, which can race with concurrent encode/decode calls.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/swift6/CodableHelper.mustache">
<violation number="1">
P1: `encode` also uses a shared `JSONEncoder` outside `OpenAPIMutex`, allowing concurrent encode/configuration mutation on the same instance.</violation>
<violation number="2">
P1: `decode` uses a shared `JSONDecoder` outside `OpenAPIMutex`, which reintroduces a race with concurrent configuration updates (for example `dateFormatter` changes). Keep decoding inside the mutex-protected state access.</violation>
</file>
<file name="samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift">
<violation number="1">
P1: `encode` runs on a shared `JSONEncoder` after leaving the mutex, allowing races with concurrent state mutations.</violation>
<violation number="2">
P1: `decode` now uses the shared `JSONDecoder` outside the mutex, so concurrent config updates can race with decoding.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
[Swift6][Client] Make Swift 6 generator thread safe
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
master(upcoming7.x.0minor release - breaking changes with fallbacks),8.0.x(breaking changes without fallbacks)"fixes #123"present in the PR description)@jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) @4brunu (2019/11) @dydus0x14 (2023/06)
Summary by cubic
Make the Swift 6 client generator thread-safe by introducing
OpenAPIMutexand refactoring configuration, helpers, and request tracking to use it. This removes data races and aligns with Swift concurrency across all Swift 6 client variants, including Vapor.Refactors
OpenAPIMutexsupporting file and included it in all generated clients; used to guard mutable state.APIConfigurationin a privateStatewith computed properties; movedsuccessfulStatusCodeRange, interceptors, and response serializers intoState.CodableHelperto guard JSON encoder/decoder and date formatters; default JSON encoder is pretty-printed.RequestTaskandSynchronizedDictionaryto useOpenAPIMutex(dictionary is nowfinal) instead ofNSRecursiveLock.beforeSendandapiWrapperare now@Sendable.Migration
beforeSend, mark it@Sendable. No other changes required.Written for commit fa52502. Summary will update on new commits.