Skip to content

Commit

Permalink
Add a maxQueueSize configuration option
Browse files Browse the repository at this point in the history
  • Loading branch information
fathyb committed Jul 16, 2018
1 parent 1ee901d commit 51e00ab
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Analytics/Classes/Internal/SEGAnalyticsUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ NSString *GenerateUUIDString(void);
// Date Utils
NSString *iso8601FormattedString(NSDate *date);

void trimQueue(NSMutableArray *array, int size);
void trimQueue(NSMutableArray *array, NSUInteger size);

// Async Utils
dispatch_queue_t seg_dispatch_queue_create_specific(const char *label,
Expand Down
2 changes: 1 addition & 1 deletion Analytics/Classes/Internal/SEGAnalyticsUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}

/** trim the queue so that it contains only upto `max` number of elements. */
void trimQueue(NSMutableArray *queue, int max)
void trimQueue(NSMutableArray *queue, NSUInteger max)
{
if (queue.count < max) {
return;
Expand Down
5 changes: 2 additions & 3 deletions Analytics/Classes/Internal/SEGSegmentIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,8 @@ - (void)enqueueAction:(NSString *)action dictionary:(NSMutableDictionary *)paylo
- (void)queuePayload:(NSDictionary *)payload
{
@try {
// We only queue upto 1000 items, so trim the queue to 1000-1=999
// before we add a new element.
trimQueue(self.queue, 999);
// Trim the queue to maxQueueSize - 1 before we add a new element.
trimQueue(self.queue, self.analytics.configuration.maxQueueSize - 1);
[self.queue addObject:payload];
[self persistQueue];
[self flushQueueByLength];
Expand Down
5 changes: 5 additions & 0 deletions Analytics/Classes/SEGAnalyticsConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ typedef NSMutableURLRequest *_Nonnull (^SEGRequestFactory)(NSURL *_Nonnull);
*/
@property (nonatomic, assign) NSTimeInterval flushInterval;

/**
* The maximum number of items to queue before starting to drop old ones. This should be a value greater than zero, the behaviour is undefined otherwise. `1000` by default.
*/
@property (nonatomic, assign) NSUInteger maxQueueSize;

/**
* Whether the analytics client should automatically make a track call for application lifecycle events, such as "Application Installed", "Application Updated" and "Application Opened".
*/
Expand Down
1 change: 1 addition & 0 deletions Analytics/Classes/SEGAnalyticsConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ - (instancetype)init
self.shouldUseBluetooth = NO;
self.flushAt = 20;
self.flushInterval = 30;
self.maxQueueSize = 1000;
_factories = [NSMutableArray array];
Class applicationClass = NSClassFromString(@"UIApplication");
if (applicationClass) {
Expand Down
27 changes: 27 additions & 0 deletions AnalyticsTests/AnalyticsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class AnalyticsTests: QuickSpec {
it("initialized correctly") {
expect(analytics.configuration.flushAt) == 20
expect(analytics.configuration.flushInterval) == 30
expect(analytics.configuration.maxQueueSize) == 1000
expect(analytics.configuration.writeKey) == "QUI5ydwIGeFFTa1IvCBUhxL9PyW5B0jE"
expect(analytics.configuration.shouldUseLocationServices) == false
expect(analytics.configuration.enableAdvertisingTracking) == true
Expand Down Expand Up @@ -108,6 +109,32 @@ class AnalyticsTests: QuickSpec {
expect(testApplication.backgroundTasks.count).toEventually(equal(1))
expect(testApplication.backgroundTasks[0].isEnded).toEventually(beFalse())
}

it("respects maxQueueSize") {
let max = 72
config.maxQueueSize = UInt(max)

for i in 1...max * 2 {
analytics.track("test #\(i)")
}

let integration = analytics.test_integrationsManager()?.test_segmentIntegration()
expect(integration).notTo(beNil())

var sent = 0

analytics.flush()
integration?.test_dispatchBackground {
if let count = integration?.test_queue()?.count {
sent = count
}
else {
sent = -1
}
}

expect(sent).toEventually(be(max))
}

it("protocol conformance should not interfere with UIApplication interface") {
// In Xcode8/iOS10, UIApplication.h typedefs UIBackgroundTaskIdentifier as NSUInteger,
Expand Down
6 changes: 6 additions & 0 deletions AnalyticsTests/Utils/TestUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ extension SEGSegmentIntegration {
func test_batchRequest() -> URLSessionUploadTask? {
return self.value(forKey: "batchRequest") as? URLSessionUploadTask
}
func test_queue() -> [AnyObject]? {
return self.value(forKey: "queue") as? [AnyObject]
}
func test_dispatchBackground(block: @convention(block) () -> Void) {
self.perform(Selector(("dispatchBackground:")), with: block)
}
}


Expand Down

0 comments on commit 51e00ab

Please sign in to comment.