Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/1260 fallback retry timeout option #1290

Merged
merged 5 commits into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Source/ARTClientOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (readwrite, assign, nonatomic) NSTimeInterval httpRequestTimeout;

/**
The period in seconds before HTTP requests are retried against the default endpoint.
(After a failed request to the default endpoint, followed by a successful request to a fallback endpoint)
*/
@property (readwrite, assign, nonatomic) NSTimeInterval fallbackRetryTimeout;

/**
Max number of fallback host retries for HTTP requests that fail due to network issues or server problems.
*/
Expand Down
3 changes: 2 additions & 1 deletion Source/ARTClientOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ - (instancetype)initDefaults {
_channelRetryTimeout = 15.0; //Seconds
_httpOpenTimeout = 4.0; //Seconds
_httpRequestTimeout = 10.0; //Seconds
_fallbackRetryTimeout = 600.0; // Seconds, TO3l10
_httpMaxRetryDuration = 15.0; //Seconds
_httpMaxRetryCount = 3;
_fallbackHosts = nil;
Expand Down Expand Up @@ -120,7 +121,7 @@ - (id)copyWithZone:(NSZone *)zone {
options.httpMaxRetryCount = self.httpMaxRetryCount;
options.httpMaxRetryDuration = self.httpMaxRetryDuration;
options.httpOpenTimeout = self.httpOpenTimeout;
options.httpRequestTimeout = self.httpRequestTimeout;
options.fallbackRetryTimeout = self.fallbackRetryTimeout;
options->_fallbackHosts = self.fallbackHosts; //ignore setter

#pragma clang diagnostic push
Expand Down
1 change: 0 additions & 1 deletion Source/ARTDefault+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ extern NSString *const ARTDefault_variant;
+ (void)setRealtimeRequestTimeout:(NSTimeInterval)value;
+ (void)setConnectionStateTtl:(NSTimeInterval)value;
+ (void)setMaxMessageSize:(NSInteger)value;
+ (void)setFallbackRetryTimeout:(NSTimeInterval)value;

@end
5 changes: 0 additions & 5 deletions Source/ARTDefault.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ NS_ASSUME_NONNULL_BEGIN

+ (NSInteger)maxMessageSize;

/**
The period in seconds before HTTP requests are retried against the default endpoint
*/
+ (NSTimeInterval)fallbackRetryTimeout;

@end

NS_ASSUME_NONNULL_END
11 changes: 0 additions & 11 deletions Source/ARTDefault.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ static inline UInt32 conformVersionComponent(const NSInteger component) {
;

static NSTimeInterval _realtimeRequestTimeout = 10.0;
static NSTimeInterval _fallbackRetryTimeout = 600.0; // TO3l10
static NSTimeInterval _connectionStateTtl = 60.0;
static NSInteger _maxMessageSize = 65536;

Expand Down Expand Up @@ -87,10 +86,6 @@ + (NSTimeInterval)ttl {
return 60 * 60;
}

+ (NSTimeInterval)fallbackRetryTimeout {
return _fallbackRetryTimeout;
}

+ (NSTimeInterval)connectionStateTtl {
return _connectionStateTtl;
}
Expand Down Expand Up @@ -121,12 +116,6 @@ + (void)setMaxMessageSize:(NSInteger)value {
}
}

+ (void)setFallbackRetryTimeout:(NSTimeInterval)value {
@synchronized (self) {
_fallbackRetryTimeout = value;
}
}

+ (NSString *)bundleVersion {
NSDictionary *infoDictionary = [[NSBundle bundleForClass: [ARTDefault class]] infoDictionary];
return infoDictionary[ARTDefault_bundleVersionKey];
Expand Down
2 changes: 1 addition & 1 deletion Source/ARTRest.m
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ - (void)setCurrentFallbackHost:(NSString *)value {

_currentFallbackHost = value;

_fallbackRetryExpiration = [ARTTime timeSinceBoot] + [ARTDefault fallbackRetryTimeout];
_fallbackRetryExpiration = [ARTTime timeSinceBoot] + _options.fallbackRetryTimeout;
}

#if TARGET_OS_IOS
Expand Down
26 changes: 3 additions & 23 deletions Spec/Tests/RestClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ private func testStoresSuccessfulFallbackHostAsDefaultHost(_ caseTest: FakeNetwo
private func testRestoresDefaultPrimaryHostAfterTimeoutExpires(_ caseTest: FakeNetworkResponse, channelName: String) {
let options = ARTClientOptions(key: "xxxx:xxxx")
options.logLevel = .debug
options.fallbackRetryTimeout = 1
let client = ARTRest(options: options)
let mockHTTP = MockHTTP(logger: options.logHandler)
testHTTPExecutor = TestProxyHTTPExecutor(http: mockHTTP, logger: options.logHandler)
Expand Down Expand Up @@ -107,6 +108,7 @@ private func testRestoresDefaultPrimaryHostAfterTimeoutExpires(_ caseTest: FakeN

private func testUsesAnotherFallbackHost(_ caseTest: FakeNetworkResponse, channelName: String) {
let options = ARTClientOptions(key: "xxxx:xxxx")
options.fallbackRetryTimeout = 10
options.logLevel = .debug
let client = ARTRest(options: options)
let mockHTTP = MockHTTP(logger: options.logHandler)
Expand Down Expand Up @@ -1187,16 +1189,14 @@ class RestClientTests: XCTestCase {
func test__049__RestClient__Host_Fallback__every_new_HTTP_request_is_first_attempted_to_the_default_primary_host_rest_ably_io() {
let options = ARTClientOptions(key: "xxxx:xxxx")
options.httpMaxRetryCount = 1
options.fallbackRetryTimeout = 1 // RSC15j exception
let client = ARTRest(options: options)
let mockHTTP = MockHTTP(logger: options.logHandler)
testHTTPExecutor = TestProxyHTTPExecutor(http: mockHTTP, logger: options.logHandler)
client.internal.httpExecutor = testHTTPExecutor
mockHTTP.setNetworkState(network: .hostUnreachable, resetAfter: 1)
let channel = client.channels.get(uniqueChannelName())

// RSC15j exception
ARTDefault.setFallbackRetryTimeout(1)

waitUntil(timeout: testTimeout) { done in
channel.publish(nil, data: "nil") { _ in
done()
Expand Down Expand Up @@ -1535,47 +1535,27 @@ class RestClientTests: XCTestCase {
testStoresSuccessfulFallbackHostAsDefaultHost(.hostInternalError(code: 501), channelName: uniqueChannelName())
}

func beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired() {
ARTDefault.setFallbackRetryTimeout(1.0)
}

func test__080__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired___hostUnreachable() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired()

testRestoresDefaultPrimaryHostAfterTimeoutExpires(.hostUnreachable, channelName: uniqueChannelName())
}

func test__081__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired___requestTimeout_timeout__0_1_() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired()

testRestoresDefaultPrimaryHostAfterTimeoutExpires(.requestTimeout(timeout: 0.1), channelName: uniqueChannelName())
}

func test__082__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired___hostInternalError_code__501_() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_restore_default_primary_host_after_fallbackRetryTimeout_expired()

testRestoresDefaultPrimaryHostAfterTimeoutExpires(.hostInternalError(code: 501), channelName: uniqueChannelName())
}

func beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded() {
ARTDefault.setFallbackRetryTimeout(10)
}

func test__083__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded___hostUnreachable() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded()

testUsesAnotherFallbackHost(.hostUnreachable, channelName: uniqueChannelName())
}

func test__084__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded___requestTimeout_timeout__0_1_() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded()

testUsesAnotherFallbackHost(.requestTimeout(timeout: 0.1), channelName: uniqueChannelName())
}

func test__085__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded___hostInternalError_code__501_() {
beforeEach__RestClient__Host_Fallback__should_store_successful_fallback_host_as_default_host__should_use_another_fallback_host_if_previous_fallback_request_failed_and_store_it_as_default_if_current_fallback_request_succseeded()

testUsesAnotherFallbackHost(.hostInternalError(code: 501), channelName: uniqueChannelName())
}

Expand Down