Skip to content

Commit 9eda29c

Browse files
fix scheduler. don't reschedule if valid timer, use optional with nil value for timeout.
1 parent 068f715 commit 9eda29c

File tree

5 files changed

+81
-11
lines changed

5 files changed

+81
-11
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
/****************************************************************************
3+
* Copyright 2019, Optimizely, Inc. and contributors *
4+
* *
5+
* Licensed under the Apache License, Version 2.0 (the "License"); *
6+
* you may not use this file except in compliance with the License. *
7+
* You may obtain a copy of the License at *
8+
* *
9+
* http://www.apache.org/licenses/LICENSE-2.0 *
10+
* *
11+
* Unless required by applicable law or agreed to in writing, software *
12+
* distributed under the License is distributed on an "AS IS" BASIS, *
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14+
* See the License for the specific language governing permissions and *
15+
* limitations under the License. *
16+
***************************************************************************/
17+
18+
19+
import Foundation
20+
21+
extension Date {
22+
func minutesPastSinceNow() -> Int {
23+
let calendar = Calendar.current
24+
return calendar.component(.minute, from: self)
25+
}
26+
}

OptimizelySDK/Implementation/DefaultDatafileHandler.swift

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ class DefaultDatafileHandler : OPTDatafileHandler {
4949
}
5050

5151
open func downloadDatafile(sdkKey: String,
52-
resourceTimeoutInterval:Double = -1,
52+
resourceTimeoutInterval:Double? = nil,
5353
completionHandler: @escaping DatafileDownloadCompletionHandler) {
5454
let config = URLSessionConfiguration.ephemeral
55-
if resourceTimeoutInterval > 0 {
55+
if let resourceTimeoutInterval = resourceTimeoutInterval,
56+
resourceTimeoutInterval > 0 {
5657
config.timeoutIntervalForResource = TimeInterval(resourceTimeoutInterval)
5758
}
5859
let session = URLSession(configuration: config)
@@ -105,11 +106,19 @@ class DefaultDatafileHandler : OPTDatafileHandler {
105106

106107
func startPeriodicUpdates(sdkKey: String, updateInterval: Int, datafileChangeNotification:((Data)->Void)?) {
107108

109+
let now = Date()
108110
if #available(iOS 10.0, tvOS 10.0, *) {
109111
DispatchQueue.main.async {
112+
if let timer = self.timers.property?[sdkKey], timer.isValid {
113+
return
114+
}
115+
110116
let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(updateInterval), repeats: false) { (timer) in
111117

112-
self.performPerodicDownload(sdkKey: sdkKey, updateInterval: updateInterval, datafileChangeNotification: datafileChangeNotification)
118+
self.performPerodicDownload(sdkKey: sdkKey,
119+
startTime: now,
120+
updateInterval: updateInterval,
121+
datafileChangeNotification: datafileChangeNotification)
113122

114123
timer.invalidate()
115124
}
@@ -120,7 +129,11 @@ class DefaultDatafileHandler : OPTDatafileHandler {
120129
} else {
121130
// Fallback on earlier versions
122131
DispatchQueue.main.async {
123-
let timer = Timer.scheduledTimer(timeInterval: TimeInterval(updateInterval), target: self, selector:#selector(self.timerFired(timer:)), userInfo: ["sdkKey": sdkKey, "updateInterval":updateInterval, "datafileChangeNotification":datafileChangeNotification ?? { (data) in }], repeats: false)
132+
if let timer = self.timers.property?[sdkKey], timer.isValid {
133+
return
134+
}
135+
136+
let timer = Timer.scheduledTimer(timeInterval: TimeInterval(updateInterval), target: self, selector:#selector(self.timerFired(timer:)), userInfo: ["sdkKey": sdkKey, "startTime": Date(), "updateInterval":updateInterval, "datafileChangeNotification":datafileChangeNotification ?? { (data) in }], repeats: false)
124137

125138
self.timers.performAtomic(atomicOperation: { (timers) in
126139
timers[sdkKey] = timer
@@ -135,8 +148,9 @@ class DefaultDatafileHandler : OPTDatafileHandler {
135148
if let info = timer.userInfo as? [String:Any],
136149
let sdkKey = info["sdkKey"] as? String,
137150
let updateInterval = info["updateInterval"] as? Int,
151+
let startDate = info["startDate"] as? Date,
138152
let datafileChangeNotification = info["datafileChangeNotification"] as? ((Data)->Void){
139-
self.performPerodicDownload(sdkKey: sdkKey, updateInterval: updateInterval, datafileChangeNotification: datafileChangeNotification)
153+
self.performPerodicDownload(sdkKey: sdkKey, startTime: startDate, updateInterval: updateInterval, datafileChangeNotification: datafileChangeNotification)
140154
}
141155
timer.invalidate()
142156

@@ -154,6 +168,7 @@ class DefaultDatafileHandler : OPTDatafileHandler {
154168
}
155169

156170
func performPerodicDownload(sdkKey: String,
171+
startTime:Date,
157172
updateInterval:Int,
158173
datafileChangeNotification:((Data)->Void)?) {
159174
self.downloadDatafile(sdkKey: sdkKey) { (result) in
@@ -168,7 +183,12 @@ class DefaultDatafileHandler : OPTDatafileHandler {
168183
}
169184

170185
if self.hasPeriodUpdates(sdkKey: sdkKey) {
171-
self.startPeriodicUpdates(sdkKey: sdkKey, updateInterval: updateInterval, datafileChangeNotification: datafileChangeNotification)
186+
let minutesSinceFire = startTime.minutesPastSinceNow()
187+
var diff = updateInterval - minutesSinceFire
188+
if diff < 0 {
189+
diff = updateInterval
190+
}
191+
self.startPeriodicUpdates(sdkKey: sdkKey, updateInterval: diff, datafileChangeNotification: datafileChangeNotification)
172192
}
173193
}
174194
}
@@ -247,6 +267,4 @@ class DefaultDatafileHandler : OPTDatafileHandler {
247267
}
248268

249269
}
250-
251-
252270
}

OptimizelySDK/Optimizely/OptimizelyManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ open class OptimizelyManager: NSObject {
7979
///
8080
/// - Parameters:
8181
/// - completion: callback when initialization is completed
82-
public func initializeSDK(resourceTimeout:Double = -1,completion: ((OptimizelyResult<Data>) -> Void)?=nil) {
82+
public func initializeSDK(resourceTimeout:Double? = nil,completion: ((OptimizelyResult<Data>) -> Void)?=nil) {
8383
fetchDatafileBackground(resourceTimeout:resourceTimeout) { result in
8484
switch result {
8585
case .failure:
@@ -176,7 +176,7 @@ open class OptimizelyManager: NSObject {
176176
}
177177
}
178178

179-
func fetchDatafileBackground(resourceTimeout:Double = -1, completion: ((OptimizelyResult<Data>) -> Void)?=nil) {
179+
func fetchDatafileBackground(resourceTimeout:Double? = nil, completion: ((OptimizelyResult<Data>) -> Void)?=nil) {
180180

181181
// TODO: fix downloadDatafile to throw OptimizelyError
182182
// those errors propagated instead of handling here

OptimizelySDK/OptimizelySwiftSDK.xcodeproj/project.pbxproj

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@
6161
0B4E11FD21EE90F600D5B370 /* DataStoreUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B4E11FB21EE90F600D5B370 /* DataStoreUserDefaults.swift */; };
6262
0B626D612242B98E00E4F7DA /* NotificationCenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B626D602242B98D00E4F7DA /* NotificationCenterTests.swift */; };
6363
0B626D622242B98E00E4F7DA /* NotificationCenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B626D602242B98D00E4F7DA /* NotificationCenterTests.swift */; };
64+
0B74A22E226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
65+
0B74A22F226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
66+
0B74A230226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
67+
0B74A231226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
68+
0B74A232226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
69+
0B74A233226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
70+
0B74A234226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
71+
0B74A235226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
72+
0B74A236226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
73+
0B74A237226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
74+
0B74A238226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
75+
0B74A239226E23EE007C873C /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B74A22D226E23EE007C873C /* Date+Extension.swift */; };
6476
0B77D04022331D1E005AA83F /* OptimizelyManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B77D03F22331D1E005AA83F /* OptimizelyManager+Extension.swift */; };
6577
0B77D04122331E0D005AA83F /* OptimizelyManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B77D03F22331D1E005AA83F /* OptimizelyManager+Extension.swift */; };
6678
0B77D04222331E0E005AA83F /* OptimizelyManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B77D03F22331D1E005AA83F /* OptimizelyManager+Extension.swift */; };
@@ -1191,6 +1203,7 @@
11911203
0B61625C21B8B82A000D7A28 /* JSONParse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONParse.swift; sourceTree = "<group>"; };
11921204
0B61625E21B8C3A9000D7A28 /* DefaultLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultLogger.swift; sourceTree = "<group>"; };
11931205
0B626D602242B98D00E4F7DA /* NotificationCenterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationCenterTests.swift; sourceTree = "<group>"; };
1206+
0B74A22D226E23EE007C873C /* Date+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Extension.swift"; sourceTree = "<group>"; };
11941207
0B77D03F22331D1E005AA83F /* OptimizelyManager+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OptimizelyManager+Extension.swift"; sourceTree = "<group>"; };
11951208
0B77D05722370526005AA83F /* BackgroundingCallbacks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundingCallbacks.swift; sourceTree = "<group>"; };
11961209
0B7B18842231D8B800A1F85D /* DataStoreMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStoreMemory.swift; sourceTree = "<group>"; };
@@ -1507,6 +1520,7 @@
15071520
0BC48EA422038491003AFD71 /* ArrayEventForDispatch+Extension.swift */,
15081521
6EA4264E22191EEC00B074B5 /* Array+Extension.swift */,
15091522
0B77D03F22331D1E005AA83F /* OptimizelyManager+Extension.swift */,
1523+
0B74A22D226E23EE007C873C /* Date+Extension.swift */,
15101524
);
15111525
path = Extensions;
15121526
sourceTree = "<group>";
@@ -2575,6 +2589,7 @@
25752589
6E4DD87D21E5251800B0C2C7 /* FeatureVariable.swift in Sources */,
25762590
6E4DD87A21E5251800B0C2C7 /* Variation.swift in Sources */,
25772591
6E4DD85B21E5250200B0C2C7 /* OPTErrorHandler.swift in Sources */,
2592+
0B74A22F226E23EE007C873C /* Date+Extension.swift in Sources */,
25782593
6E4DD85921E5250200B0C2C7 /* OPTBucketer.swift in Sources */,
25792594
6E4DD86521E5250B00B0C2C7 /* EventForDispatch.swift in Sources */,
25802595
0B7B18862231D8B800A1F85D /* DataStoreMemory.swift in Sources */,
@@ -2639,6 +2654,7 @@
26392654
0B7B9EC621F51AF700056589 /* DataStoreFile.swift in Sources */,
26402655
6E4DD8B321E5260700B0C2C7 /* OPTNotificationCenter.swift in Sources */,
26412656
6E7C0B7721F1372600ECFF34 /* OptimizelyLogLevel.swift in Sources */,
2657+
0B74A236226E23EE007C873C /* Date+Extension.swift in Sources */,
26422658
6E4DD8D621E5274300B0C2C7 /* UserAttribute.swift in Sources */,
26432659
6E4DD8D821E5274600B0C2C7 /* ConditionHolder.swift in Sources */,
26442660
6E4DD88821E525F600B0C2C7 /* BatchEventBuilder.swift in Sources */,
@@ -2708,6 +2724,7 @@
27082724
6E636BDC2236C9B100AF3CEF /* EventForDispatch.swift in Sources */,
27092725
6EF4B4E5223836C1002DE8B6 /* BackgroundingCallbacks.swift in Sources */,
27102726
6E636C042236C9C500AF3CEF /* ArrayEventForDispatch+Extension.swift in Sources */,
2727+
0B74A232226E23EE007C873C /* Date+Extension.swift in Sources */,
27112728
6E636BBD2236C99300AF3CEF /* DataStoreMemory.swift in Sources */,
27122729
6E636BF42236C9BC00AF3CEF /* FeatureVariable.swift in Sources */,
27132730
6EA0721F223AC72D00F447CF /* Utils.swift in Sources */,
@@ -2780,6 +2797,7 @@
27802797
6E636BDE2236C9B200AF3CEF /* EventForDispatch.swift in Sources */,
27812798
6E636C092236C9C500AF3CEF /* ArrayEventForDispatch+Extension.swift in Sources */,
27822799
6E636BC12236C99400AF3CEF /* DataStoreMemory.swift in Sources */,
2800+
0B74A235226E23EE007C873C /* Date+Extension.swift in Sources */,
27832801
6E636C002236C9BD00AF3CEF /* FeatureVariable.swift in Sources */,
27842802
6E636C102236C9CB00AF3CEF /* MurmurHash3.swift in Sources */,
27852803
6E636BB12236C98400AF3CEF /* DefaultLogger.swift in Sources */,
@@ -2820,6 +2838,7 @@
28202838
6EA425312218E4A300B074B5 /* DefaultNotificationCenter.swift in Sources */,
28212839
6EA425472218E4A300B074B5 /* FeatureVariable.swift in Sources */,
28222840
6EA425222218E46C00B074B5 /* OptimizelyManager.swift in Sources */,
2841+
0B74A237226E23EE007C873C /* Date+Extension.swift in Sources */,
28232842
6E0AFBC42257C49800BC7665 /* BucketTests_Others.swift in Sources */,
28242843
6EA425482218E4A300B074B5 /* TrafficAllocation.swift in Sources */,
28252844
6EA425502218E4A300B074B5 /* DataStoreQueueStackImpl+Extension.swift in Sources */,
@@ -2954,6 +2973,7 @@
29542973
6EA4261B2218E74F00B074B5 /* DefaultUserProfileService.swift in Sources */,
29552974
6EA4261C2218E74F00B074B5 /* OPTLogger.swift in Sources */,
29562975
6EA4263F2218E74F00B074B5 /* Experiment.swift in Sources */,
2976+
0B74A238226E23EE007C873C /* Date+Extension.swift in Sources */,
29572977
6EA426322218E74F00B074B5 /* ConditionHolder.swift in Sources */,
29582978
6EA425A82218E6AE00B074B5 /* EventTests.swift in Sources */,
29592979
6EA426382218E74F00B074B5 /* Attribute.swift in Sources */,
@@ -2994,6 +3014,7 @@
29943014
6EA425DC2218E74D00B074B5 /* ArrayEventForDispatch+Extension.swift in Sources */,
29953015
6EA425CC2218E74D00B074B5 /* UserAttribute.swift in Sources */,
29963016
6E24C4B72257F5E600DF3D71 /* BatchEventBuilderTests_Events.swift in Sources */,
3017+
0B74A231226E23EE007C873C /* Date+Extension.swift in Sources */,
29973018
6EA425D72218E74D00B074B5 /* Experiment.swift in Sources */,
29983019
6EA425C52218E74D00B074B5 /* DataStoreQueueStack.swift in Sources */,
29993020
6EA425D62218E74D00B074B5 /* FeatureFlag.swift in Sources */,
@@ -3128,6 +3149,7 @@
31283149
6EA425E72218E74E00B074B5 /* DefaultUserProfileService.swift in Sources */,
31293150
6EA425E82218E74E00B074B5 /* OPTLogger.swift in Sources */,
31303151
6EA4260B2218E74E00B074B5 /* Experiment.swift in Sources */,
3152+
0B74A233226E23EE007C873C /* Date+Extension.swift in Sources */,
31313153
6EA425FE2218E74E00B074B5 /* ConditionHolder.swift in Sources */,
31323154
6EA425992218E6AD00B074B5 /* EventTests.swift in Sources */,
31333155
6EA426042218E74E00B074B5 /* Attribute.swift in Sources */,
@@ -3181,6 +3203,7 @@
31813203
6EA42687221925B100B074B5 /* Audience.swift in Sources */,
31823204
6EA426CC221925DE00B074B5 /* OptimizelyResult.swift in Sources */,
31833205
6EDE920E22273EE500840112 /* OTUtils.swift in Sources */,
3206+
0B74A234226E23EE007C873C /* Date+Extension.swift in Sources */,
31843207
6EA426D1221925DE00B074B5 /* DefaultUserProfileService.swift in Sources */,
31853208
6EA426B2221925BB00B074B5 /* OPTDataStore.swift in Sources */,
31863209
6EA42692221925B100B074B5 /* Event.swift in Sources */,
@@ -3248,6 +3271,7 @@
32483271
6EA4269A221925B300B074B5 /* Audience.swift in Sources */,
32493272
6EA426D6221925DF00B074B5 /* OptimizelyResult.swift in Sources */,
32503273
6EDE920F22273EE600840112 /* OTUtils.swift in Sources */,
3274+
0B74A239226E23EE007C873C /* Date+Extension.swift in Sources */,
32513275
6EA426DB221925DF00B074B5 /* DefaultUserProfileService.swift in Sources */,
32523276
6EA426BA221925BC00B074B5 /* OPTDataStore.swift in Sources */,
32533277
6EA426A5221925B300B074B5 /* Event.swift in Sources */,
@@ -3331,6 +3355,7 @@
33313355
6E4DD84E21E5250200B0C2C7 /* OPTBucketer.swift in Sources */,
33323356
6E4DD86321E5250B00B0C2C7 /* EventForDispatch.swift in Sources */,
33333357
0BC48EA32203764E003AFD71 /* DataStoreQueueStackImpl+Extension.swift in Sources */,
3358+
0B74A22E226E23EE007C873C /* Date+Extension.swift in Sources */,
33343359
0BE644ED223821D3009A5D1D /* AtomicProperty.swift in Sources */,
33353360
6E4DD84721E524FB00B0C2C7 /* MurmurHash3.swift in Sources */,
33363361
);
@@ -3393,6 +3418,7 @@
33933418
6E4DD8A321E5260600B0C2C7 /* OPTDecisionService.swift in Sources */,
33943419
6E4DD88A21E525FC00B0C2C7 /* DefaultNotificationCenter.swift in Sources */,
33953420
6E4DD8AA21E5260600B0C2C7 /* JSONParse.swift in Sources */,
3421+
0B74A230226E23EE007C873C /* Date+Extension.swift in Sources */,
33963422
6E4DD89C21E5260100B0C2C7 /* Result.swift in Sources */,
33973423
6E4DD89021E525FC00B0C2C7 /* DefaultDatafileHandler.swift in Sources */,
33983424
0B05901A2209DC180007F4A2 /* HandlerRegistryService.swift in Sources */,

OptimizelySDK/Protocols/OPTDatafileHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public protocol OPTDatafileHandler {
4747
- Parameter completionHhandler: listener to call when datafile download complete
4848
*/
4949
func downloadDatafile(sdkKey:String,
50-
resourceTimeoutInterval:Double,
50+
resourceTimeoutInterval:Double?,
5151
completionHandler:@escaping DatafileDownloadCompletionHandler)
5252

5353
/**

0 commit comments

Comments
 (0)