Skip to content

Commit 97b05a3

Browse files
author
Fernando Fernandes
committed
Refactor around logging and retrying
1 parent 1f0dabe commit 97b05a3

8 files changed

+103
-66
lines changed

Package.resolved

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftTrader/Common/SwiftTraderLogger.swift

Lines changed: 0 additions & 41 deletions
This file was deleted.

Sources/SwiftTrader/Network/Kucoin/AccountOverview/KucoinFuturesAccountOverviewRequest.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Foundation
99
#if canImport(FoundationNetworking)
1010
import FoundationNetworking
1111
#endif
12+
import Logging
1213

1314
/// A **request** for an overview of a Kucoin Futures account.
1415
///
@@ -19,11 +20,8 @@ public struct KucoinFuturesAccountOverviewRequest: NetworkRequest {
1920

2021
public typealias DecodableModel = KucoinFuturesAccountOverview
2122

22-
public var logger: SwiftTraderLogger {
23-
SwiftTraderLogger(
24-
label: "swift-trader.account-overview",
25-
isLoggingEnabled: settings.isLoggingEnable
26-
)
23+
public var logger: Logger {
24+
NetworkRequestLogger().default
2725
}
2826

2927
public var session: URLSession
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// NetworkRequestLogger.swift
3+
//
4+
//
5+
// Created by Fernando Fernandes on 04.02.22.
6+
//
7+
8+
import Foundation
9+
import Logging
10+
11+
/// Logs information via Apple's `swift-log` package.
12+
public struct NetworkRequestLogger {
13+
14+
// MARK: - Properties
15+
16+
public let `default`: Logger
17+
18+
// MARK: - Lifecycle
19+
20+
public init(label: String = "com.backslash-f.network") {
21+
self.default = Logger(label: label)
22+
}
23+
}

Sources/SwiftTrader/Network/NetworkRequest/NetworkRequestProtocol+Execution.swift

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,43 +17,49 @@ public extension NetworkRequest {
1717

1818
// MARK: - Default Execution
1919

20-
/// Executes the given request asynchronously (`async/await`) and returns the result.
20+
/// Executes the `NetworkRequest.getter:request` asynchronously and returns the `NetworkRequestResult`.
21+
///
22+
/// Failed requests are to be retried `n` times, according to the `numberOfRetries` of `NetworkRequest.getter:settings`.
2123
///
22-
/// - Parameter request: `URLRequest` containing the target `URL`.
2324
/// - Returns: `NetworkRequestResult`.
24-
func execute(attemptNumber: Int = 1) async -> NetworkRequestResult {
25-
let req: URLRequest
25+
func execute() async -> NetworkRequestResult {
26+
let urlRequest: URLRequest
2627
do {
27-
req = try request
28+
urlRequest = try request
2829
} catch {
2930
return .failure(.invalidRequest(error: error))
3031
}
32+
return await executeRetrying(request: urlRequest)
33+
}
34+
}
35+
36+
// MARK: - Private
37+
38+
private extension NetworkRequest {
39+
40+
func executeRetrying(request: URLRequest, attemptNumber: Int = 1) async -> NetworkRequestResult {
41+
let result: NetworkRequestResult
3142
#if os(macOS) || os(iOS)
32-
let result = await runOnApplePlatforms(request: req)
43+
result = await runOnApplePlatforms(request: request)
44+
#elseif canImport(FoundationNetworking)
45+
result = await runOnLinux(request: req)
46+
#endif
3347
switch result {
3448
case .success:
3549
return result
3650
case .failure:
3751
if attemptNumber <= settings.numberOfRetries {
38-
logger.log(message: "Retrying... \(attemptNumber) of \(settings.numberOfRetries)")
52+
log(message: "Retrying... \(attemptNumber) of \(settings.numberOfRetries)")
3953
try? await Task.sleep(nanoseconds: 1_000_000_000 * settings.delayBetweenRetries)
40-
return await execute(attemptNumber: attemptNumber + 1)
54+
return await executeRetrying(request: request, attemptNumber: attemptNumber + 1)
4155
} else {
4256
return result
4357
}
4458
}
45-
#elseif canImport(FoundationNetworking)
46-
return await runOnLinux(request: req)
47-
#endif
4859
}
49-
}
50-
51-
// MARK: - Private
52-
53-
private extension NetworkRequest {
5460

5561
#if os(macOS) || os(iOS)
56-
/// macOS and iOS.
62+
/// `async/await` can be simply called on macOS and iOS platforms; no further action is needed.
5763
func runOnApplePlatforms(request: URLRequest) async -> NetworkRequestResult {
5864
do {
5965
let (data, response) = try await session.data(for: request)
@@ -64,7 +70,7 @@ private extension NetworkRequest {
6470
}
6571
#endif
6672

67-
/// `async/await` isn't fully ported to Linux; use "withCheckedContinuation(function:_:)" instead.
73+
/// `async/await` isn't fully ported to Linux; use "**withCheckedContinuation(function:_:)**" instead.
6874
func runOnLinux(request: URLRequest) async -> NetworkRequestResult {
6975
let (data, response, error) = await withCheckedContinuation { continuation in
7076
session.dataTask(with: request) { data, response, error in
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// NetworkRequestProtocol+Logging.swift
3+
//
4+
//
5+
// Created by Fernando Fernandes on 04.02.22.
6+
//
7+
8+
import Foundation
9+
import Logging
10+
11+
/// Holds the default logging implementation.
12+
public extension NetworkRequest {
13+
14+
func log(message: Logger.Message) {
15+
guard settings.isLoggingEnable else {
16+
return
17+
}
18+
logger.log(level: settings.logLevel, message)
19+
}
20+
}

Sources/SwiftTrader/Network/NetworkRequest/NetworkRequestProtocol.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ public typealias NetworkRequestResult = Result<Decodable, NetworkRequestError>
1616
/// Represents a generic network request composed by basic functions that make a network request possible.
1717
public protocol NetworkRequest {
1818
associatedtype DecodableModel: Decodable
19-
var logger: SwiftTraderLogger { get }
19+
var logger: Logger { get }
2020
var session: URLSession { get }
2121
var request: URLRequest { get throws }
2222
var settings: NetworkRequestSettings { get }
23-
func execute(attemptNumber: Int) async -> NetworkRequestResult
23+
func execute() async -> NetworkRequestResult
2424
func decode(_ data: Data) throws -> DecodableModel
25+
func log(message: Logger.Message)
2526
}

Sources/SwiftTrader/Network/NetworkRequest/NetworkRequestSettingsProtocol.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66
//
77

88
import Foundation
9+
import Logging
910

1011
/// Conform to this protocol to provide/tweak default `NetworkRequest` settings.
1112
public protocol NetworkRequestSettings {
1213

1314
/// `true` to enable logging of network requests.
1415
var isLoggingEnable: Bool { get }
1516

17+
/// The log level.
18+
var logLevel: Logger.Level { get }
19+
1620
/// The number of retries of failed `NetworkRequest`s.
1721
var numberOfRetries: Int { get }
1822

@@ -25,6 +29,7 @@ public struct DefaultNetworkRequestSettings: NetworkRequestSettings {
2529

2630
// MARK: - Properties
2731

32+
public var logLevel: Logger.Level = .debug
2833
public var isLoggingEnable: Bool = true
2934
public var numberOfRetries: Int = 3
3035
public var delayBetweenRetries: UInt64 = 2

0 commit comments

Comments
 (0)