From 7416221080322fb17c0079c35d0ab7a360fdf9b8 Mon Sep 17 00:00:00 2001 From: Cornelius Horstmann Date: Sun, 23 Jul 2017 15:56:22 +0200 Subject: [PATCH] Fixed a bug, where the tracker would stop automatic dispatching. (#169) --- CHANGELOG.md | 1 + PiwikTracker.xcodeproj/project.pbxproj | 2 +- PiwikTracker/PiwikTracker.swift | 12 +++++++++--- PiwikTrackerTests/DispatcherStub.swift | 3 +-- PiwikTrackerTests/QueueStub.swift | 18 +++++++++++++++--- PiwikTrackerTests/TrackerFixtures.swift | 6 ++++++ PiwikTrackerTests/TrackerSpec.swift | 24 +++++++++++++++++++++++- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbed07cb..41898936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * **feature** Transmitting the Screen resolution to the Piwik Backend. [#149](https://github.com/piwik/piwik-sdk-ios/issues/149) (by @akshaykolte) * **feature** Added a Logger that can log messages in different levels. [#147](https://github.com/piwik/piwik-sdk-ios/issues/147) * **feature** Added macOS and tvOS compatibility. [#134](https://github.com/piwik/piwik-sdk-ios/issues/134) +* **bugfix** Fixed a bug, where the tracker would stop automatic dispatching. [#167](https://github.com/piwik/piwik-sdk-ios/issues/167) ## 4.0.0 * **feature** Renamed the Tracker to PiwikTracker. [#146](https://github.com/piwik/piwik-sdk-ios/issues/146) diff --git a/PiwikTracker.xcodeproj/project.pbxproj b/PiwikTracker.xcodeproj/project.pbxproj index bf41d6e9..79655588 100644 --- a/PiwikTracker.xcodeproj/project.pbxproj +++ b/PiwikTracker.xcodeproj/project.pbxproj @@ -106,6 +106,7 @@ 1F1949F51E17B2A400458199 /* Fixtures */ = { isa = PBXGroup; children = ( + 1F6F0CDA1E61E377008170FC /* TrackerFixtures.swift */, 1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */, ); name = Fixtures; @@ -167,7 +168,6 @@ 1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */, 1F6F0CD81E61E377008170FC /* DispatcherStub.swift */, 1F6F0CD91E61E377008170FC /* QueueStub.swift */, - 1F6F0CDA1E61E377008170FC /* TrackerFixtures.swift */, 1F6F0CDB1E61E377008170FC /* TrackerSpec.swift */, 1FCA6D4B1DBE0B2F0033F01C /* Info.plist */, ); diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index 1148810b..09215a7e 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -96,6 +96,7 @@ final public class PiwikTracker: NSObject { guard events.count > 0 else { // there are no more events queued, finish dispatching self.isDispatching = false + self.startDispatchTimer() self.logger.info("Finished dispatching events") return } @@ -104,16 +105,21 @@ final public class PiwikTracker: NSObject { self.logger.info("Dispatched batch of \(events.count) events.") self.dispatchBatch() }) - }, failure: { shouldContinue in - self.logger.warning("Failed dispatching events with error \(shouldContinue)") + }, failure: { error in self.isDispatching = false + self.startDispatchTimer() + self.logger.warning("Failed dispatching events with error \(error)") }) } } // MARK: dispatch timer - private let dispatchInterval: TimeInterval = 30.0 // Discussion: move this into a configuration? + public var dispatchInterval: TimeInterval = 30.0 { + didSet { + startDispatchTimer() + } + } private var dispatchTimer: Timer? private func startDispatchTimer() { diff --git a/PiwikTrackerTests/DispatcherStub.swift b/PiwikTrackerTests/DispatcherStub.swift index 408e062f..53e7670f 100644 --- a/PiwikTrackerTests/DispatcherStub.swift +++ b/PiwikTrackerTests/DispatcherStub.swift @@ -12,8 +12,7 @@ final class DispatcherStub: Dispatcher { let userAgent: String? = "DispatcherStub" - - func send(event: Event, success: @escaping ()->(), failure: @escaping (Error)->()){ + func send(event: Event, success: @escaping () -> (), failure: @escaping (Error) -> ()) { send(events: [event], success: success, failure: failure) } diff --git a/PiwikTrackerTests/QueueStub.swift b/PiwikTrackerTests/QueueStub.swift index 623a5a0a..534113ae 100644 --- a/PiwikTrackerTests/QueueStub.swift +++ b/PiwikTrackerTests/QueueStub.swift @@ -21,15 +21,27 @@ final class QueueStub: Queue { } func enqueue(events: [Event], completion: (()->())?) { - queueEvents?(events, completion ?? {}) + if let closure = queueEvents { + closure(events, completion ?? {}) + } else { + completion?() + } } func first(limit: Int, completion: ([Event]) -> ()) { - firstItems?(limit, completion) + if let closure = firstItems { + closure(limit, completion) + } else { + completion([]) + } } func remove(events: [Event], completion: () -> ()) { - removeEventsCallback?(events, completion) + if let closure = removeEventsCallback { + closure(events, completion) + } else { + completion() + } } } diff --git a/PiwikTrackerTests/TrackerFixtures.swift b/PiwikTrackerTests/TrackerFixtures.swift index 41f8229e..b78c9c8e 100644 --- a/PiwikTrackerTests/TrackerFixtures.swift +++ b/PiwikTrackerTests/TrackerFixtures.swift @@ -34,4 +34,10 @@ struct TrackerFixture { dispatcher.sendEvents = sendEvents return TrackerFixture(queue: queue, dispatcher: dispatcher) } + + static func withSendEventsCallback(sendEvents: @escaping DispatcherStub.Callback.SendEvents) -> TrackerFixture { + let dispatcher = DispatcherStub() + dispatcher.sendEvents = sendEvents + return TrackerFixture(queue: MemoryQueue(), dispatcher: dispatcher) + } } diff --git a/PiwikTrackerTests/TrackerSpec.swift b/PiwikTrackerTests/TrackerSpec.swift index c35941f3..22376406 100644 --- a/PiwikTrackerTests/TrackerSpec.swift +++ b/PiwikTrackerTests/TrackerSpec.swift @@ -48,9 +48,31 @@ class TrackerSpec: QuickSpec { } it("should stop dispatching if the queue is empty") { - } } + it("should start a new DispatchTimer if dispatching failed") { + var numberOfDispatches = 0 + let trackerFixture = TrackerFixture.withSendEventsCallback() { events, success, failure in + numberOfDispatches += 1 + failure(NSError(domain: "spec", code: 0)) + } + trackerFixture.tracker.queue(event: EventFixture.event()) + trackerFixture.tracker.dispatchInterval = 0.1 + expect(numberOfDispatches).toEventually(equal(5), timeout: 5) + } + it("should start a new DispatchTimer if dispatching succeeded") { + var numberOfDispatches = 0 + let trackerFixture = TrackerFixture.withSendEventsCallback() { events, success, failure in + numberOfDispatches += 1 + success() + } + trackerFixture.tracker.queue(event: EventFixture.event()) + let _ = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + trackerFixture.tracker.queue(event: EventFixture.event()) + } + trackerFixture.tracker.dispatchInterval = 0.1 + expect(numberOfDispatches).toEventually(equal(5), timeout: 5) + } context("with an already dispatching tracker") { it("should not ask the queue for events") { // TODO