Skip to content

Commit

Permalink
Merge pull request #86 from launchdarkly/dz/allowFlagPolling
Browse files Browse the repository at this point in the history
Add interval-based polling mode
  • Loading branch information
arun251 authored Apr 6, 2017
2 parents d63e733 + 188c759 commit 7dea04b
Show file tree
Hide file tree
Showing 17 changed files with 343 additions and 84 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to the LaunchDarkly Python SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).

## [2.2.0] - 2017-04-05
### Added
- Ability to disable streaming and enable interval-based polling

## [2.1.3] - 2017-04-05
### Fixed
- Uncaught exception `NSInvalidArgumentException` in `performEventRequest`
Expand Down
4 changes: 3 additions & 1 deletion Darkly/DarklyConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ extern NSString *const kLDBackgroundFetchInitiated;
extern int const kCapacity;
extern int const kConnectionTimeout;
extern int const kDefaultFlushInterval;
extern int const kMinimumPollingIntervalMillis;
extern int const kMinimumFlushIntervalMillis;
extern int const kDefaultPollingInterval;
extern int const kMinimumPollingInterval;
extern int const kMillisInSecs;
6 changes: 4 additions & 2 deletions Darkly/DarklyConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#import "DarklyConstants.h"

NSString * const kClientVersion = @"2.1.3";
NSString * const kClientVersion = @"2.2.0";
NSString * const kBaseUrl = @"https://app.launchdarkly.com";
NSString * const kEventsUrl = @"https://mobile.launchdarkly.com";
NSString * const kStreamUrl = @"https://stream.launchdarkly.com/mping";
Expand All @@ -25,5 +25,7 @@
int const kCapacity = 100;
int const kConnectionTimeout = 10;
int const kDefaultFlushInterval = 30;
int const kMinimumPollingIntervalMillis = 0;
int const kMinimumFlushIntervalMillis = 0;
int const kDefaultPollingInterval = 3600;
int const kMinimumPollingInterval = 300;
int const kMillisInSecs = 1000;
2 changes: 1 addition & 1 deletion Darkly/LDClientManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

- (void)syncWithServerForEvents;
- (void)syncWithServerForConfig;
- (void)processedEvents:(BOOL)success jsonEventArray:(NSArray *)jsonEventArray eventIntervalMillis:(int)eventIntervalMillis;
- (void)processedEvents:(BOOL)success jsonEventArray:(NSArray *)jsonEventArray;
- (void)processedConfig:(BOOL)success jsonConfigDictionary:(NSDictionary *)jsonConfigDictionary;
- (void)startPolling;
- (void)stopPolling;
Expand Down
58 changes: 37 additions & 21 deletions Darkly/LDClientManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,22 @@ +(LDClientManager *)sharedInstance {
- (void)startPolling {
LDPollingManager *pollingMgr = [LDPollingManager sharedInstance];

LDClient *client = [LDClient sharedInstance];
LDConfig *config = client.ldConfig;
pollingMgr.eventTimerPollingIntervalMillis = [config.flushInterval intValue] * kMillisInSecs;
DEBUG_LOG(@"ClientManager startPolling method called with eventTimerPollingInterval=%f", pollingMgr.eventTimerPollingIntervalMillis);
LDConfig *config = [[LDClient sharedInstance] ldConfig];
pollingMgr.eventPollingIntervalMillis = [config.flushInterval intValue] * kMillisInSecs;
DEBUG_LOG(@"ClientManager startPolling method called with pollingInterval=%f", pollingMgr.eventPollingIntervalMillis);
[pollingMgr startEventPolling];

eventSource = [EventSource eventSourceWithURL:[NSURL URLWithString:kStreamUrl] mobileKey:config.mobileKey];

[eventSource onMessage:^(Event *e) {
[self syncWithServerForConfig];
}];
if ([config streaming]) {
eventSource = [EventSource eventSourceWithURL:[NSURL URLWithString:kStreamUrl] mobileKey:config.mobileKey];

[eventSource onMessage:^(Event *e) {
[self syncWithServerForConfig];
}];
}
else{
pollingMgr.configPollingIntervalMillis = [config.pollingInterval intValue] * kMillisInSecs;
[pollingMgr startConfigPolling];
}
}


Expand All @@ -53,7 +58,12 @@ - (void)stopPolling {

[pollingMgr stopEventPolling];

[eventSource close];
if ([[[LDClient sharedInstance] ldConfig] streaming]) {
[eventSource close];
}
else{
[pollingMgr stopConfigPolling];
}

[self flushEvents];
}
Expand All @@ -64,7 +74,12 @@ - (void)willEnterBackground {

[pollingMgr suspendEventPolling];

[eventSource close];
if ([[[LDClient sharedInstance] ldConfig] streaming]) {
[eventSource close];
}
else{
[pollingMgr suspendConfigPolling];
}

[self flushEvents];
}
Expand All @@ -75,11 +90,17 @@ - (void)willEnterForeground {
[pollingMgr resumeEventPolling];

LDClient *client = [LDClient sharedInstance];
eventSource = [EventSource eventSourceWithURL:[NSURL URLWithString:kStreamUrl] mobileKey:client.ldConfig.mobileKey];

[eventSource onMessage:^(Event *e) {
[self syncWithServerForConfig];
}];
if ([[client ldConfig] streaming]) {
eventSource = [EventSource eventSourceWithURL:[NSURL URLWithString:kStreamUrl] mobileKey:client.ldConfig.mobileKey];

[eventSource onMessage:^(Event *e) {
[self syncWithServerForConfig];
}];
}
else{
[pollingMgr resumeConfigPolling];
}
}

-(void)syncWithServerForEvents {
Expand Down Expand Up @@ -124,19 +145,14 @@ - (void)flushEvents {
[self syncWithServerForEvents];
}

- (void)processedEvents:(BOOL)success jsonEventArray:(NSArray *)jsonEventArray eventIntervalMillis:(int)eventIntervalMillis {
- (void)processedEvents:(BOOL)success jsonEventArray:(NSArray *)jsonEventArray {
// If Success
if (success) {
DEBUG_LOGX(@"ClientManager processedEvents method called after receiving successful response from server");
// Audit cached events versus processed Events and only keep difference
if (jsonEventArray) {
[[LDDataManager sharedManager] deleteProcessedEvents: jsonEventArray];
}
} else {
DEBUG_LOGX(@"ClientManager processedEvents method called after receiving failure response from server");
LDPollingManager *pollingMgr = [LDPollingManager sharedInstance];
DEBUG_LOG(@"ClientManager setting event interval to: %d", eventIntervalMillis);
pollingMgr.eventTimerPollingIntervalMillis = eventIntervalMillis;
}
}

Expand Down
22 changes: 20 additions & 2 deletions Darkly/LDConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
@property (nonatomic) NSNumber* capacity;
@property (nonatomic) NSNumber* connectionTimeout;
@property (nonatomic) NSNumber* flushInterval;
@property (nonatomic) NSNumber* pollingInterval;
@property (nonatomic) BOOL streaming;
@property (nonatomic) BOOL debugEnabled;

@end
Expand Down Expand Up @@ -65,15 +67,31 @@
- (LDConfigBuilder *)withConnectionTimeout:(int)connectionTimeout;
/**
* The interval at which events are synced to the server. The default
* is 30 seconds. (Optional)
* is 30 seconds for streaming mode; in polling mode, the flush interval defaults to the polling interval. (Optional)
*
* @param flushInverval the flush interval in seconds
* @param flushInterval the flush interval in seconds
* @return the configuration builder
*/
- (LDConfigBuilder *)withFlushInterval:(int)flushInterval;
/**
* Set the polling interval (in seconds) for polling mode only. An interval
* less than 300 is set to the default (5 minutes).
*
* @param pollingInterval the polling interval in seconds
* @return the configuration builder
*/
- (LDConfigBuilder *)withPollingInterval:(int)pollingInterval;
/**
* Enable streaming mode for flags. When streaming is false, disable streaming and switch to polling mode. (Optional)
*
* @param streamingEnabled Whether streaming is enabled or not
* @return the configuration builder
*/
- (LDConfigBuilder *)withStreaming:(BOOL)streamingEnabled;
/**
* Enable debug mode to allow things such as logging. (Optional)
*
* @param debugEnabled Whether debugging is enabled or not
* @return the configuration builder
*/
- (LDConfigBuilder *)withDebugEnabled:(BOOL)debugEnabled;
Expand Down
35 changes: 33 additions & 2 deletions Darkly/LDConfig.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@implementation LDConfig

@synthesize mobileKey, baseUrl, eventsUrl, capacity, connectionTimeout, flushInterval, debugEnabled;
@synthesize mobileKey, baseUrl, eventsUrl, capacity, connectionTimeout, flushInterval, pollingInterval, streaming, debugEnabled;

@end

Expand All @@ -18,13 +18,21 @@ @interface LDConfigBuilder() {
NSNumber *capacity;
NSNumber *connectionTimeout;
NSNumber *flushInterval;
NSNumber *pollingInterval;
BOOL streaming;
BOOL debugEnabled;
}

@end

@implementation LDConfigBuilder

- (id)init {
self = [super init];
streaming = YES;
return self;
}

- (LDConfigBuilder *)withMobileKey:(NSString *)inputMobileKey
{
mobileKey = inputMobileKey;
Expand Down Expand Up @@ -60,6 +68,18 @@ - (LDConfigBuilder *)withFlushInterval:(int)inputFlushInterval
return self;
}

- (LDConfigBuilder *)withPollingInterval:(int)inputPollingInterval
{
pollingInterval = [NSNumber numberWithInt:MAX(inputPollingInterval, kMinimumPollingInterval)];
return self;
}

- (LDConfigBuilder *)withStreaming:(BOOL)inputStreamingEnabled
{
streaming = inputStreamingEnabled;
return self;
}

- (LDConfigBuilder *)withDebugEnabled:(BOOL)inputDebugEnabled
{
debugEnabled = inputDebugEnabled;
Expand Down Expand Up @@ -112,11 +132,22 @@ -(LDConfig *)build
DEBUG_LOG(@"LDConfigBuilder building LDConfig with default flush interval: %d", kDefaultFlushInterval);
[config setFlushInterval:[NSNumber numberWithInt:kDefaultFlushInterval]];
}
if (pollingInterval) {
DEBUG_LOG(@"LDConfigBuilder building LDConfig with polling interval: %@", pollingInterval);
[config setPollingInterval:pollingInterval];
} else {
DEBUG_LOG(@"LDConfigBuilder building LDConfig with default polling interval: %d", kDefaultPollingInterval);
[config setPollingInterval:[NSNumber numberWithInt:kDefaultPollingInterval]];
}

DEBUG_LOG(@"LDConfigBuilder building LDConfig with streaming enabled: %d", streaming);
[config setStreaming:streaming];

if (debugEnabled) {
DEBUG_LOG(@"LDConfigBuilder building LDConfig with debug enabled: %d", debugEnabled);
[config setDebugEnabled:debugEnabled];
}
return config;
}

@end
@end
20 changes: 16 additions & 4 deletions Darkly/LDPollingManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,30 @@ typedef enum {
@interface LDPollingManager : NSObject
{
@protected
PollingState pollEventState;
PollingState configPollingState;
PollingState eventPollingState;
}


+ (id)sharedInstance;
@property (nonatomic, assign) PollingState pollEventState;
@property (nonatomic, assign) PollingState configPollingState;
@property (nonatomic, assign) PollingState eventPollingState;

@property (strong, nonatomic) dispatch_source_t configTimer;
@property (nonatomic) NSTimeInterval configPollingIntervalMillis;
@property (strong, nonatomic) dispatch_source_t eventTimer;
@property (nonatomic) NSTimeInterval eventTimerPollingIntervalMillis;
@property (nonatomic) NSTimeInterval eventPollingIntervalMillis;

+ (NSUInteger)configPollingCount;
+ (NSUInteger)eventPollingCount;

- (void) startConfigPolling;
- (void) pauseConfigPolling;
- (void) suspendConfigPolling;
- (void) resumeConfigPolling;
- (void) stopConfigPolling;
- (PollingState)configPollingState;

// event polling is passed in from the LDClient object. can be modified...
- (void) startEventPolling;
- (void) pauseEventPolling;
Expand All @@ -34,4 +46,4 @@ typedef enum {
- (void) stopEventPolling;
- (PollingState)eventPollingState;

@end
@end
Loading

0 comments on commit 7dea04b

Please sign in to comment.