@@ -47,6 +47,7 @@ public class Reporter {
4747 self . batterySafeForNetworking = batterySafeForNetworking
4848 self . rateLimiter = rateLimiter ?? ReporterRateLimiter ( configs: session. configuration. reporterRateLimits)
4949 self . queue = queue ?? InstanaPersistableQueue < CoreBeacon > ( identifier: " com.instana.ios.mainqueue " , maxItems: session. configuration. maxQueueSize)
50+ purgeOldBeacons ( session. configuration. deleteOldBeacons)
5051 networkUtility. connectionUpdateHandler = { [ weak self] connectionType in
5152 guard let self = self else { return }
5253 self . updateNetworkConnection ( connectionType)
@@ -60,6 +61,20 @@ public class Reporter {
6061 dispatchQueue. asyncAfter ( deadline: . now( ) + session. configuration. preQueueUsageTime, execute: emptyPreQueueIfNeeded)
6162 }
6263
64+ func purgeOldBeacons( _ deleteOldBeacons: Bool , minutes: Double = 15.0 ) {
65+ if !deleteOldBeacons {
66+ return
67+ }
68+ let cutoffTime = Date ( ) . millisecondsSince1970 - Int64( minutes * 60.0 * 1000.0 )
69+ var updatedBeacons : Set < CoreBeacon > = [ ]
70+ for coreBeacon in queue. items {
71+ if let timestamp = Int64 ( coreBeacon. ti) , timestamp > cutoffTime {
72+ updatedBeacons. insert ( coreBeacon)
73+ }
74+ }
75+ queue. items = updatedBeacons
76+ }
77+
6378 func submit( _ beacon: Beacon , _ completion: ( ( Bool ) -> Void ) ? = nil ) {
6479 dispatchQueue. async { [ weak self] in
6580 guard let self = self else { return }
@@ -196,13 +211,14 @@ public class Reporter {
196211 debounce = calcDebounceTime ( )
197212 beacons = queue. items
198213 }
214+
199215 let flusher = BeaconFlusher ( reporter: self , items: beacons, debounce: debounce,
200216 config: session. configuration, queue: dispatchQueue,
201217 send: send) { [ weak self] result in
202218 guard let self = self else { return }
203219 self . dispatchQueue. async { [ weak self] in
204- guard let self = self else { return }
205- self . handle ( flushResult: result, start, fromBeaconFlusherCompletion: true )
220+ let originalBeacons : Set < CoreBeacon > ? = ( result . sentBeacons . count < beacons . count ) ? beacons : nil
221+ self ? . handle ( flushResult: result, start, fromBeaconFlusherCompletion: true , originalBeacons : originalBeacons )
206222 }
207223 }
208224 flusher. schedule ( )
@@ -237,7 +253,8 @@ public class Reporter {
237253
238254 private func handle( flushResult: BeaconFlusher . Result ,
239255 _ start: Date = Date ( ) ,
240- fromBeaconFlusherCompletion: Bool = false ) {
256+ fromBeaconFlusherCompletion: Bool = false ,
257+ originalBeacons: Set < CoreBeacon > ? = nil ) {
241258 let result : BeaconResult
242259 let errors = flushResult. errors
243260 let sent = flushResult. sentBeacons
@@ -253,13 +270,36 @@ public class Reporter {
253270 result = BeaconResult . failure ( error)
254271 session. logger. add ( " Failed to send beacons in \( end * 1000 ) ms " )
255272 }
256- queue. remove ( sent) { [ weak self] _ in
257- guard let self = self else { return }
258- self . completionHandler. forEach { $0 ( result) }
273+
274+ if originalBeacons == nil {
275+ // All beacons were successfully sent. Remove them from local file.
276+ queue. remove ( sent) { [ weak self] _ in
277+ self ? . completionHandler. forEach { $0 ( result) }
278+ }
279+ } else {
280+ // For beacons failed sending, increase retry count and save back to file.
281+ queue. items. subtract ( sent)
282+ var updatedBeacons : Set < CoreBeacon > = [ ]
283+ for var cBeacon in queue. items {
284+ if originalBeacons!. contains ( cBeacon) {
285+ cBeacon. increaseRetryCount ( )
286+ if cBeacon. rct! < session. configuration. maxBeaconResendTries {
287+ updatedBeacons. insert ( cBeacon)
288+ } // else: throw away the beacon
289+ } else {
290+ // new beacons, keep as is
291+ updatedBeacons. insert ( cBeacon)
292+ }
293+ }
294+ queue. items = updatedBeacons
295+ queue. write { [ weak self] _ in
296+ self ? . completionHandler. forEach { $0 ( result) }
297+ }
259298 }
260299
261300 if fromBeaconFlusherCompletion {
262301 flusher = nil // mark this round flush done
302+ lastFlushStartTime = nil
263303 if inSlowModeBeforeFlush {
264304 // Another flush either resend 1 beacon (still in slow mode currently)
265305 // or flush remaining beacons (got out of slow send mode already)
0 commit comments