swagger-api / swagger-api/swagger-codegen
[Swift] Alamofire client template does not support concurrent request
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
The current Alamofire client template implementation does not support concurrent requests. The static AlamofireRequestBuilder.execute method adds an instance of Alamofire.SessionManager to a global variable (managerStore) without any thread safe mechanism to avoid concurrent accesses. Therefore this can result, for example, in the deallocation of a Alamofire.SessionManager that might cancel the request. As result, the requests affect will return Error Domain=NSURLErrorDomain Code=-999 "cancelled".
Swagger-codegen version
2.3.1, 3.0.5
Swagger declaration file content or url
Not needed, all applications making concurrent requests using the Alamofire implementation of these version should experience the same issues.
Command line used for generation
swagger-codegen-2.3.1 generate -i http://localhost:8083/api-docs/v1/swagger.json -l swift4 -o swagger-client
Steps to reproduce
Dispatch several concurrent operation to a OperationQueue performing different API requests. Check if any of these calls resulted in a cancelled request.
Suggest a fix/enhancement
I can think about two different solutions that could help in the resolution of this problem:
- Instead of using static methods, relying on global variables/state and create on each request a new session manager, we could instead use an API Client instance that would be injected/kept in memory and configurable as needed.
- Make the global variable thread safe. We could use something like this:
public final class Synchronized<T> {
private let queue: DispatchQueue
private var _value: T
public init(_ value: T) {
let queueLabel = "com.codegen.synchronized.\(type(of: value)).\(UUID().uuidString)"
self.queue = DispatchQueue(label: queueLabel, attributes: .concurrent)
self._value = value
}
public var value: T {
var result: T? = nil
queue.sync { result = self._value }
return result!
}
public func write(using block: @escaping (inout T) -> Void) {
queue.async(flags: .barrier) {
block(&self._value)
}
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the AlamofireRequestBuilder.execute entry point and inspect how managerStore holds Alamofire.SessionManager instances. Reproduce the problem by dispatching several requests through an OperationQueue, then verify that concurrent requests complete without cancellation and add or update coverage if the relevant template tests are found.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- api, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100