@@ -16,29 +16,24 @@ extension REST {
16
16
class MullvadApiNetworkOperation < Success: Sendable > : ResultOperation < Success > , @unchecked Sendable {
17
17
private let logger : Logger
18
18
19
- private let requestHandler : MullvadApiRequestHandler
19
+ private let request : APIRequest
20
+ private let transportProvider : APITransportProviderProtocol
20
21
private var responseDecoder : JSONDecoder
21
22
private let responseHandler : any RESTRustResponseHandler < Success >
22
- private var networkTask : MullvadApiCancellable ?
23
-
24
- private let retryStrategy : RetryStrategy
25
- private var retryDelayIterator : AnyIterator < Duration >
26
- private var retryTimer : DispatchSourceTimer ?
27
- private var retryCount = 0
23
+ private var networkTask : Cancellable ?
28
24
29
25
init (
30
26
name: String ,
31
27
dispatchQueue: DispatchQueue ,
32
- retryStrategy : RetryStrategy ,
33
- requestHandler : @escaping MullvadApiRequestHandler ,
28
+ request : APIRequest ,
29
+ transportProvider : APITransportProviderProtocol ,
34
30
responseDecoder: JSONDecoder ,
35
31
responseHandler: some RESTRustResponseHandler < Success > ,
36
32
completionHandler: CompletionHandler ? = nil
37
33
) {
38
- self . retryStrategy = retryStrategy
39
- retryDelayIterator = retryStrategy. makeDelayIterator ( )
34
+ self . request = request
40
35
self . responseDecoder = responseDecoder
41
- self . requestHandler = requestHandler
36
+ self . transportProvider = transportProvider
42
37
self . responseHandler = responseHandler
43
38
44
39
var logger = Logger ( label: " REST.RustNetworkOperation " )
@@ -53,10 +48,7 @@ extension REST {
53
48
}
54
49
55
50
override public func operationDidCancel( ) {
56
- retryTimer? . cancel ( )
57
51
networkTask? . cancel ( )
58
-
59
- retryTimer = nil
60
52
networkTask = nil
61
53
}
62
54
@@ -72,97 +64,30 @@ extension REST {
72
64
return
73
65
}
74
66
75
- networkTask = requestHandler { [ weak self] response in
67
+ let transport = transportProvider. makeTransport ( )
68
+ networkTask = transport? . sendRequest ( request) { [ weak self] response in
76
69
guard let self else { return }
77
70
78
- if let error = response. restError ( ) {
79
- if response. shouldRetry {
80
- retryRequest ( with: error)
81
- } else {
82
- finish ( result: . failure( error) )
83
- }
84
-
71
+ if let errorWrapper = response. error, let error = errorWrapper. originalError {
72
+ finish ( result: . failure( error) )
85
73
return
86
74
}
87
75
88
- let decodedResponse = responseHandler. handleResponse ( response)
76
+ let decodedResponse = responseHandler. handleResponse ( response. data )
89
77
90
78
switch decodedResponse {
91
79
case let . success( value) :
92
80
finish ( result: . success( value) )
93
81
case let . decoding( block) :
94
- finish ( result: . success( try block ( ) ) )
82
+ do {
83
+ finish ( result: . success( try block ( ) ) )
84
+ } catch {
85
+ finish ( result: . failure( REST . Error. unhandledResponse ( 0 , nil ) ) )
86
+ }
95
87
case let . unhandledResponse( error) :
96
- finish ( result: . failure( REST . Error. unhandledResponse ( Int ( response . statusCode ) , error) ) )
88
+ finish ( result: . failure( REST . Error. unhandledResponse ( 0 , error) ) )
97
89
}
98
90
}
99
91
}
100
-
101
- private func retryRequest( with error: REST . Error ) {
102
- // Check if retry count is not exceeded.
103
- guard retryCount < retryStrategy. maxRetryCount else {
104
- if retryStrategy. maxRetryCount > 0 {
105
- logger. debug ( " Ran out of retry attempts ( \( retryStrategy. maxRetryCount) ) " )
106
- }
107
- finish ( result: . failure( error) )
108
- return
109
- }
110
-
111
- // Increment retry count.
112
- retryCount += 1
113
-
114
- // Retry immediately if retry delay is set to never.
115
- guard retryStrategy. delay != . never else {
116
- startRequest ( )
117
- return
118
- }
119
-
120
- guard let waitDelay = retryDelayIterator. next ( ) else {
121
- logger. debug ( " Retry delay iterator failed to produce next value. " )
122
-
123
- finish ( result: . failure( error) )
124
- return
125
- }
126
-
127
- logger. debug ( " Retry in \( waitDelay. logFormat ( ) ) . " )
128
-
129
- // Create timer to delay retry.
130
- let timer = DispatchSource . makeTimerSource ( queue: dispatchQueue)
131
-
132
- timer. setEventHandler { [ weak self] in
133
- self ? . startRequest ( )
134
- }
135
-
136
- timer. setCancelHandler { [ weak self] in
137
- self ? . finish ( result: . failure( OperationError . cancelled) )
138
- }
139
-
140
- timer. schedule ( wallDeadline: . now( ) + waitDelay. timeInterval)
141
- timer. activate ( )
142
-
143
- retryTimer = timer
144
- }
145
92
}
146
93
}
147
-
148
- extension MullvadApiResponse {
149
- public func restError( ) -> REST . Error ? {
150
- guard !success else {
151
- return nil
152
- }
153
-
154
- guard let serverResponseCode else {
155
- return . transport( MullvadApiTransportError . connectionFailed ( description: errorDescription) )
156
- }
157
-
158
- let response = REST . ServerErrorResponse (
159
- code: REST . ServerResponseCode ( rawValue: serverResponseCode) ,
160
- detail: errorDescription
161
- )
162
- return . unhandledResponse( Int ( statusCode) , response)
163
- }
164
- }
165
-
166
- enum MullvadApiTransportError : Error {
167
- case connectionFailed( description: String ? )
168
- }
0 commit comments