Skip to content

Commit

Permalink
Improving atomic code by using Atomic property wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
LucianoPAlmeida committed Dec 15, 2019
1 parent 00de5d7 commit 4b697f0
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 32 deletions.
4 changes: 4 additions & 0 deletions Moya.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
A6304A7E74FA3B04C9B10B63 /* AccessTokenPluginSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BAAD7EC02607A52AD3EF1E /* AccessTokenPluginSpec.swift */; };
A8C55515DFA147BE4159B40A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EFCB6731C60D3830DA5D2CB /* Response.swift */; };
AB5048DC5042B016964EE958 /* MoyaProvider+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371C174EF53873DE04BB159E /* MoyaProvider+Reactive.swift */; };
B2CD7F4F23A6F1BA007F67AC /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2CD7F4E23A6F1BA007F67AC /* Atomic.swift */; };
B4ABD55950B0E70BF44E79C6 /* MoyaProviderIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82E52DC541FD052ABA625D2A /* MoyaProviderIntegrationTests.swift */; };
B5A7124CF285D8EC7F89C1AD /* CredentialsPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 884642F58B074C95261DCA86 /* CredentialsPlugin.swift */; };
B950CAA84C0656EB11E316FB /* MultiTargetSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D11E4BE1D5112E6972AD09F /* MultiTargetSpec.swift */; };
Expand Down Expand Up @@ -204,6 +205,7 @@
9C38151BF038BA0B61EF5A62 /* TargetType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetType.swift; sourceTree = "<group>"; };
B184F8E91A84A02E209EEB91 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MultipartFormData.swift; sourceTree = "<group>"; };
B1F68927EA26EBDB45E82C8C /* MoyaProviderSpec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MoyaProviderSpec.swift; sourceTree = "<group>"; };
B2CD7F4E23A6F1BA007F67AC /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
C79C5F376B4A2C3F70051980 /* Error+MoyaSpec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "Error+MoyaSpec.swift"; sourceTree = "<group>"; };
C841AA621AEC61FAEA0CA019 /* MoyaProvider+ReactiveSpec.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "MoyaProvider+ReactiveSpec.swift"; sourceTree = "<group>"; };
CC115388D44D0DB7A753E9BB /* AccessTokenPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AccessTokenPlugin.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -308,6 +310,7 @@
331A6D3090D9773091435406 /* Moya */ = {
isa = PBXGroup;
children = (
B2CD7F4E23A6F1BA007F67AC /* Atomic.swift */,
149749421F8923EC00FA4900 /* AnyEncodable.swift */,
5C2B20158E599EDBE51D7AB2 /* Cancellable.swift */,
3FF1994427C5440527B03B31 /* Endpoint.swift */,
Expand Down Expand Up @@ -832,6 +835,7 @@
3AF7063CBE1F9626FB32D933 /* Cancellable.swift in Sources */,
85F6042E22A018BB00063320 /* RequestTypeWrapper.swift in Sources */,
49C61E884A595E94758B5643 /* Endpoint.swift in Sources */,
B2CD7F4F23A6F1BA007F67AC /* Atomic.swift in Sources */,
FB223B5C3B7D4AA5261E25EA /* Image.swift in Sources */,
EDBA10DB0D0E35C1474AAB4D /* Moya+Alamofire.swift in Sources */,
15D3A2BD1223B59E2BBE09F0 /* MoyaError.swift in Sources */,
Expand Down
31 changes: 31 additions & 0 deletions Sources/Moya/Atomic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Atomic.swift
// Moya
//
// Created by Luciano Almeida on 15/12/19.
//

import Foundation

@propertyWrapper
final class Atomic<Value> {
private var lock: NSRecursiveLock = NSRecursiveLock()

private var value: Value

var wrappedValue: Value {
get {
lock.lock(); defer { lock.unlock() }
return value
}

set {
lock.lock(); defer { lock.unlock() }
value = newValue
}
}

init(wrappedValue value: Value) {
self.value = value
}
}
16 changes: 2 additions & 14 deletions Sources/Moya/Moya+Alamofire.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,10 @@ extension DownloadRequest: Requestable {
}

final class MoyaRequestInterceptor: RequestInterceptor {
private let lock: NSRecursiveLock = NSRecursiveLock()

var prepare: ((URLRequest) -> URLRequest)?
private var internalWillSend: ((URLRequest) -> Void)?

var willSend: ((URLRequest) -> Void)? {
get {
lock.lock(); defer { lock.unlock() }
return internalWillSend
}

set {
lock.lock(); defer { lock.unlock() }
internalWillSend = newValue
}
}
@Atomic
var willSend: ((URLRequest) -> Void)?

init(prepare: ((URLRequest) -> URLRequest)? = nil, willSend: ((URLRequest) -> Void)? = nil) {
self.prepare = prepare
Expand Down
13 changes: 3 additions & 10 deletions Sources/Moya/MoyaProvider+Internal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,14 @@ public extension MoyaProvider {
}

if trackInflights {
lock.lock()
var inflightCompletionBlocks = self.inflightRequests[endpoint]
inflightCompletionBlocks?.append(pluginsWithCompletion)
self.inflightRequests[endpoint] = inflightCompletionBlocks
lock.unlock()
self.internalInflightRequests[endpoint] = inflightCompletionBlocks

if inflightCompletionBlocks != nil {
return cancellableToken
} else {
lock.lock()
self.inflightRequests[endpoint] = [pluginsWithCompletion]
lock.unlock()
self.internalInflightRequests[endpoint] = [pluginsWithCompletion]
}
}

Expand All @@ -65,10 +61,7 @@ public extension MoyaProvider {
let networkCompletion: Moya.Completion = { result in
if self.trackInflights {
self.inflightRequests[endpoint]?.forEach { $0(result) }

self.lock.lock()
self.inflightRequests.removeValue(forKey: endpoint)
self.lock.unlock()
self.internalInflightRequests.removeValue(forKey: endpoint)
} else {
pluginsWithCompletion(result)
}
Expand Down
8 changes: 5 additions & 3 deletions Sources/Moya/MoyaProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ open class MoyaProvider<Target: TargetType>: MoyaProviderType {

public let trackInflights: Bool

open internal(set) var inflightRequests: [Endpoint: [Moya.Completion]] = [:]
open var inflightRequests: [Endpoint: [Moya.Completion]] { internalInflightRequests }

@Atomic
var internalInflightRequests: [Endpoint: [Moya.Completion]] = [:]

/// Propagated to Alamofire as callback queue. If nil - the Alamofire default (as of their API in 2017 - the main queue) will be used.
let callbackQueue: DispatchQueue?
Expand Down Expand Up @@ -189,8 +192,7 @@ public extension MoyaProvider {
}

/// Return a response after a delay.
final class func delayedStub(_ seconds: TimeInterval) -> (Target) -> Moya.StubBehavior {
{ _ in .delayed(seconds: seconds) }
final class func delayedStub(_ seconds: TimeInterval) -> (Target) -> Moya.StubBehavior { { _ in .delayed(seconds: seconds) }
}
}

Expand Down
3 changes: 1 addition & 2 deletions Sources/ReactiveMoya/MoyaProvider+Reactive.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public extension Reactive where Base: MoyaProviderType {

/// Designated request-making method with progress.
func requestWithProgress(_ token: Base.Target, callbackQueue: DispatchQueue? = nil) -> SignalProducer<ProgressResponse, MoyaError> {
let progressBlock: (Signal<ProgressResponse, MoyaError>.Observer) -> (ProgressResponse) -> Void = { observer in
{ progress in
let progressBlock: (Signal<ProgressResponse, MoyaError>.Observer) -> (ProgressResponse) -> Void = { observer in { progress in
observer.send(value: progress)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/ReactiveMoya/SignalProducer+Response.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private func unwrapThrowable<T>(throwable: () throws -> T) -> SignalProducer<T,
return SignalProducer(error: error)
} else {
// The cast above should never fail, but just in case.
return SignalProducer(error: MoyaError.underlying(error as NSError, nil))
return SignalProducer(error: MoyaError.underlying(error, nil))
}
}
}
3 changes: 1 addition & 2 deletions Sources/RxMoya/MoyaProvider+Rx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public extension Reactive where Base: MoyaProviderType {

/// Designated request-making method with progress.
func requestWithProgress(_ token: Base.Target, callbackQueue: DispatchQueue? = nil) -> Observable<ProgressResponse> {
let progressBlock: (AnyObserver) -> (ProgressResponse) -> Void = { observer in
{ progress in
let progressBlock: (AnyObserver) -> (ProgressResponse) -> Void = { observer in { progress in
observer.onNext(progress)
}
}
Expand Down

0 comments on commit 4b697f0

Please sign in to comment.