Skip to content

Commit ce163d0

Browse files
authored
feat(ats): add configurable timeouts for ODP segment fetch and event dispatch (#471)
1 parent 2898a18 commit ce163d0

14 files changed

+126
-23
lines changed

.github/workflows/source_clear_cron.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99

1010
jobs:
1111
source_clear:
12-
runs-on: macos-latest
12+
runs-on: macos-12
1313
steps:
1414
- uses: actions/checkout@v3
1515
- name: Source clear scan

.github/workflows/swift.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
3333

3434
lint:
35-
runs-on: macos-latest
35+
runs-on: macos-12
3636
steps:
3737
- uses: actions/checkout@v3
3838
- uses: maxim-lobanov/setup-xcode@v1
@@ -47,10 +47,12 @@ jobs:
4747
4848
unittests:
4949
if: "${{ github.event.inputs.PREP == '' && github.event.inputs.RELEASE == '' }}"
50-
uses: optimizely/swift-sdk/.github/workflows/unit_tests.yml@master
50+
# restore back to master after merging.
51+
#uses: optimizely/swift-sdk/.github/workflows/unit_tests.yml@master
52+
uses: optimizely/swift-sdk/.github/workflows/unit_tests.yml@jae/ats-timeout
5153

5254
prepare_for_release:
53-
runs-on: macos-latest
55+
runs-on: macos-12
5456
if: "${{ github.event.inputs.PREP == 'true' && github.event_name == 'workflow_dispatch' }}"
5557
steps:
5658
- uses: actions/checkout@v3
@@ -74,7 +76,7 @@ jobs:
7476

7577
release:
7678
if: "${{github.event.inputs.RELEASE == 'true' && github.event_name == 'workflow_dispatch' }}"
77-
runs-on: macos-latest
79+
runs-on: macos-12
7880
steps:
7981
- uses: actions/checkout@v3
8082
- uses: maxim-lobanov/setup-xcode@v1

.github/workflows/unit_tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ jobs:
5050
- uses: actions/checkout@v3
5151
- uses: maxim-lobanov/setup-xcode@v1
5252
with:
53-
xcode-version: 14.1.0
53+
# macos version and supported simulator_xcode_versions are all related to this xcode_version, so be careful when you upgrade this.
54+
xcode-version: 12.4
5455
- name: set SDK Branch if PR
5556
if: ${{ github.event_name == 'pull_request' }}
5657
run: |

Sources/ODP/OdpEventApiManager.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ import Foundation
3131
*/
3232

3333
class OdpEventApiManager {
34-
34+
let resourceTimeoutInSecs: Int?
35+
36+
/// OdpEventApiManager init
37+
/// - Parameters:
38+
/// - timeout: timeout for segment fetch
39+
init(timeout: Int? = nil) {
40+
self.resourceTimeoutInSecs = timeout
41+
}
42+
3543
func sendOdpEvents(apiKey: String,
3644
apiHost: String,
3745
events: [OdpEvent],
@@ -99,8 +107,12 @@ class OdpEventApiManager {
99107
task.resume()
100108
}
101109

102-
func getSession() -> URLSession {
103-
return URLSession(configuration: .ephemeral)
110+
open func getSession() -> URLSession {
111+
let config = URLSessionConfiguration.ephemeral
112+
if let timeout = resourceTimeoutInSecs, timeout > 0 {
113+
config.timeoutIntervalForResource = TimeInterval(timeout)
114+
}
115+
return URLSession(configuration: config)
104116
}
105-
117+
106118
}

Sources/ODP/OdpEventManager.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,18 @@ class OdpEventManager {
2828

2929
let logger = OPTLoggerFactory.getLogger()
3030

31-
init(sdkKey: String, odpConfig: OdpConfig? = nil, apiManager: OdpEventApiManager? = nil) {
31+
/// OdpEventManager init
32+
/// - Parameters:
33+
/// - sdkKey: datafile sdkKey
34+
/// - odpConfig: ODP config (apiKey, apiHost, ...)
35+
/// - apiManager: OdpEventApiManager
36+
/// - resourceTimeoutInSecs: timeout for event dispatch
37+
init(sdkKey: String,
38+
odpConfig: OdpConfig? = nil,
39+
apiManager: OdpEventApiManager? = nil,
40+
resourceTimeoutInSecs: Int? = nil) {
3241
self.odpConfig = odpConfig ?? OdpConfig()
33-
self.apiMgr = apiManager ?? OdpEventApiManager()
42+
self.apiMgr = apiManager ?? OdpEventApiManager(timeout: resourceTimeoutInSecs)
3443

3544
self.queueLock = DispatchQueue(label: "event")
3645

Sources/ODP/OdpManager.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,22 @@ class OdpManager {
3030
return vuidManager.vuid
3131
}
3232

33+
/// OdpManager init
34+
/// - Parameters:
35+
/// - sdkKey: datafile sdkKey
36+
/// - disable: disable ODP
37+
/// - cacheSize: segment cache size
38+
/// - cacheTimeoutInSecs: segment cache timeout
39+
/// - timeoutForSegmentFetchInSecs: timeout for segment fetch
40+
/// - timeoutForEventDispatchInSecs: timeout for event dispatch
41+
/// - segmentManager: ODPSegmentManager
42+
/// - eventManager: ODPEventManager
3343
init(sdkKey: String,
3444
disable: Bool,
3545
cacheSize: Int,
3646
cacheTimeoutInSecs: Int,
47+
timeoutForSegmentFetchInSecs: Int? = nil,
48+
timeoutForEventDispatchInSecs: Int? = nil,
3749
segmentManager: OdpSegmentManager? = nil,
3850
eventManager: OdpEventManager? = nil) {
3951

@@ -53,14 +65,17 @@ class OdpManager {
5365
} else {
5466
self.segmentManager = OdpSegmentManager(cacheSize: cacheSize,
5567
cacheTimeoutInSecs: cacheTimeoutInSecs,
56-
odpConfig: odpConfig)
68+
odpConfig: odpConfig,
69+
resourceTimeoutInSecs: timeoutForSegmentFetchInSecs)
5770
}
5871

5972
if let eventManager = eventManager {
6073
eventManager.odpConfig = odpConfig
6174
self.eventManager = eventManager
6275
} else {
63-
self.eventManager = OdpEventManager(sdkKey: sdkKey, odpConfig: odpConfig)
76+
self.eventManager = OdpEventManager(sdkKey: sdkKey,
77+
odpConfig: odpConfig,
78+
resourceTimeoutInSecs: timeoutForEventDispatchInSecs)
6479
}
6580

6681
self.eventManager.registerVUID(vuid: self.vuidManager.vuid)

Sources/ODP/OdpSegmentApiManager.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ import Foundation
9797

9898
class OdpSegmentApiManager {
9999
let logger = OPTLoggerFactory.getLogger()
100+
let resourceTimeoutInSecs: Int?
101+
102+
/// OdpSegmentApiManager init
103+
/// - Parameters:
104+
/// - timeout: timeout for segment fetch
105+
init(timeout: Int? = nil) {
106+
self.resourceTimeoutInSecs = timeout
107+
}
100108

101109
func fetchSegments(apiKey: String,
102110
apiHost: String,
@@ -175,8 +183,12 @@ class OdpSegmentApiManager {
175183
task.resume()
176184
}
177185

178-
func getSession() -> URLSession {
179-
return URLSession(configuration: .ephemeral)
186+
open func getSession() -> URLSession {
187+
let config = URLSessionConfiguration.ephemeral
188+
if let timeout = resourceTimeoutInSecs, timeout > 0 {
189+
config.timeoutIntervalForResource = TimeInterval(timeout)
190+
}
191+
return URLSession(configuration: config)
180192
}
181193

182194
func makeQuery(userKey: String, userValue: String, segmentsToCheck: [String]) -> [String: Any] {

Sources/ODP/OdpSegmentManager.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@ class OdpSegmentManager {
2323

2424
let logger = OPTLoggerFactory.getLogger()
2525

26+
/// OdpSegmentManager init
27+
/// - Parameters:
28+
/// - cacheSize: segment cache size
29+
/// - cacheTimeoutInSecs: segment cache timeout
30+
/// - odpConfig: ODP config (apiKey, apiHost, ...)
31+
/// - apiManager: OdpSegmentApiManager
32+
/// - resourceTimeoutInSecs: timeout for segment fetch
2633
init(cacheSize: Int,
2734
cacheTimeoutInSecs: Int,
2835
odpConfig: OdpConfig? = nil,
29-
apiManager: OdpSegmentApiManager? = nil) {
36+
apiManager: OdpSegmentApiManager? = nil,
37+
resourceTimeoutInSecs: Int? = nil) {
3038
self.odpConfig = odpConfig ?? OdpConfig()
31-
self.apiMgr = apiManager ?? OdpSegmentApiManager()
39+
self.apiMgr = apiManager ?? OdpSegmentApiManager(timeout: resourceTimeoutInSecs)
3240

3341
self.segmentsCache = LruCache<String, [String]>(size: cacheSize,
3442
timeoutInSecs: cacheTimeoutInSecs)

Sources/ODP/OptimizelySdkSettings.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public struct OptimizelySdkSettings {
2121
let segmentsCacheSize: Int
2222
/// The timeout in seconds of audience segments cache - timeout is disabled if this is set to zero.
2323
let segmentsCacheTimeoutInSecs: Int
24+
/// The timeout in seconds of odp segment fetch - OS default timeout will be used if this is set to zero.
25+
let timeoutForSegmentFetchInSecs: Int
26+
/// The timeout in seconds of odp event dispatch - OS default timeout will be used if this is set to zero.
27+
let timeoutForOdpEventInSecs: Int
2428
/// ODP features are disabled if this is set to true.
2529
let disableOdp: Bool
2630

@@ -29,12 +33,18 @@ public struct OptimizelySdkSettings {
2933
/// - Parameters:
3034
/// - segmentsCacheSize: The maximum size of audience segments cache (optional. default = 100). Set to zero to disable caching.
3135
/// - segmentsCacheTimeoutInSecs: The timeout in seconds of audience segments cache (optional. default = 600). Set to zero to disable timeout.
36+
/// - timeoutForSegmentFetchInSecs: The timeout in seconds of odp segment fetch (optional. default = 10) - OS default timeout will be used if this is set to zero.
37+
/// - timeoutForOdpEventInSecs: The timeout in seconds of odp event dispatch (optional. default = 10) - OS default timeout will be used if this is set to zero.
3238
/// - disableOdp: Set this flag to true (default = false) to disable ODP features
3339
public init(segmentsCacheSize: Int = 100,
3440
segmentsCacheTimeoutInSecs: Int = 600,
41+
timeoutForSegmentFetchInSecs: Int = 10,
42+
timeoutForOdpEventInSecs: Int = 10,
3543
disableOdp: Bool = false) {
3644
self.segmentsCacheSize = segmentsCacheSize
3745
self.segmentsCacheTimeoutInSecs = segmentsCacheTimeoutInSecs
46+
self.timeoutForSegmentFetchInSecs = timeoutForSegmentFetchInSecs
47+
self.timeoutForOdpEventInSecs = timeoutForOdpEventInSecs
3848
self.disableOdp = disableOdp
3949
}
4050
}

Sources/Optimizely/OptimizelyClient.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ open class OptimizelyClient: NSObject {
9191
self.odpManager = OdpManager(sdkKey: sdkKey,
9292
disable: sdkSettings.disableOdp,
9393
cacheSize: sdkSettings.segmentsCacheSize,
94-
cacheTimeoutInSecs: sdkSettings.segmentsCacheTimeoutInSecs)
94+
cacheTimeoutInSecs: sdkSettings.segmentsCacheTimeoutInSecs,
95+
timeoutForSegmentFetchInSecs: sdkSettings.timeoutForSegmentFetchInSecs,
96+
timeoutForEventDispatchInSecs: sdkSettings.timeoutForOdpEventInSecs)
9597

9698
super.init()
9799

0 commit comments

Comments
 (0)