Created by: DavidHorvath
resolve #8658 (closed)
Previously the generated clients didn't support cancellation of requests
I've added request cancellation for:
- Both URLSession & Alamofire library
- Combine configuration
- RxSwift configuration
- Result configuration
- AsyncAwait configuration
For these clients I have updated the RequestBuilder's execute function so it returns an optional URLSessionDataTask
.
I've also added @discardableResult
to keep backward compatibility.
Default
I've added to return the URLSessionDataTask
so the user will be able to control the request's lifecycle.
@discardableResult
open class func addPet(body: Pet, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> URLSessionDataTask? {
return addPetWithRequestBuilder(body: body).execute(apiResponseQueue) { result in
switch result {
case .success:
completion((), nil)
case let .failure(error):
completion(nil, error)
}
}
}
Result
I've added to return the URLSessionDataTask
so the user will be able to control the request's lifecycle.
@discardableResult
open class func addPet(body: Pet, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, completion: @escaping ((_ result: Swift.Result<Void, ErrorResponse>) -> Void)) -> URLSessionTask? {
return addPetWithRequestBuilder(body: body).execute(apiResponseQueue) { result in
switch result {
case .success:
completion(.success(()))
case let .failure(error):
completion(.failure(error))
}
}
}
Combine
I've implemented handeEvents(receiveCompletion: where I cancel the returned URLSessionDataTask
when the stream is cancelled
open class func addPet(body: Pet, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue) -> AnyPublisher<Void, Error> {
var dataTask: URLSessionDataTask?
return Future<Void, Error> { promise in
dataTask = addPetWithRequestBuilder(body: body).execute(apiResponseQueue) { result in
switch result {
case .success:
promise(.success(()))
case let .failure(error):
promise(.failure(error))
}
}
}
.handleEvents(receiveCancel: {
dataTask?.cancel()
})
.eraseToAnyPublisher()
}
RxSwift
I've added to cancel the returned URLSessionDataTask
in Disposables.create
when the stream is cancelled
open class func addPet(body: Pet, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue) -> Observable<Void> {
return Observable.create { observer -> Disposable in
let dataTask = addPetWithRequestBuilder(body: body).execute(apiResponseQueue) { result in
switch result {
case .success:
observer.onNext(())
case let .failure(error):
observer.onError(error)
}
observer.onCompleted()
}
return Disposables.create {
dataTask?.cancel()
}
}
}
Async Await
I've added to cancel the returned URLSessionDataTask
in withTaskCancellationHandler.onCancel:
open class func addPet(body: Pet, apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue) async throws {
var task: URLSessionTask?
return try await withTaskCancellationHandler {
try Task.checkCancellation()
return try await withCheckedThrowingContinuation { continuation in
guard !Task.isCancelled else {
continuation.resume(throwing: CancellationError())
return
}
task = addPetWithRequestBuilder(body: body).execute(apiResponseQueue) { result in
switch result {
case .success:
continuation.resume(returning: ())
case let .failure(error):
continuation.resume(throwing: error)
}
}
}
} onCancel: { [task] in
task?.cancel()
}
}
PR checklist
-
Read the contribution guidelines. -
Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community. -
Run the following to build the project and update samples: ./mvnw clean package ./bin/generate-samples.sh ./bin/utils/export_docs_generators.sh
./bin/generate-samples.sh bin/configs/java*
. For Windows users, please run the script in Git BASH. -
File the PR against the correct branch: master
(5.3.0),6.0.x
-
If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request. @4brunu