Skip to content

Commit b7a83c1

Browse files
Add background timeouts for iOS (#1531)
It is expected the background downloading is longer than the foreground one. And even more on iOS the app is not really performing background downloading. So it is better to have separate timeouts. Relates-To: DATASDK-19 Signed-off-by: Rustam Gamidov <ext-rustam.gamidov@here.com>
1 parent 5607b77 commit b7a83c1

File tree

8 files changed

+183
-9
lines changed

8 files changed

+183
-9
lines changed

olp-cpp-sdk-core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ add_library(${PROJECT_NAME} ${OLP_SDK_CORE_SOURCES} ${OLP_SDK_CORE_HEADERS})
413413

414414
if (OLP_SDK_ENABLE_IOS_BACKGROUND_DOWNLOAD)
415415
target_compile_definitions(${PROJECT_NAME}
416-
PRIVATE OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD)
416+
PUBLIC OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD)
417417
endif()
418418

419419
if (OLP_SDK_DISABLE_DEBUG_LOGGING)

olp-cpp-sdk-core/include/olp/core/client/RetrySettings.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021-2023 HERE Europe B.V.
2+
* Copyright (C) 2021-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -76,6 +76,18 @@ struct CORE_API RetrySettings {
7676
*/
7777
int timeout = 60;
7878

79+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
80+
/**
81+
* @brief Maximum time for background request to complete (in seconds).
82+
*
83+
* The default value is 600.
84+
*
85+
* @note Connection or data transfer will be interrupted after specified
86+
* period of time ignoring `connection_timeout` and `transfer_timeout` values.
87+
*/
88+
int background_timeout = 600;
89+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
90+
7991
/**
8092
* @brief Time allowed to wait for connection to establish (in milliseconds).
8193
*
@@ -86,6 +98,20 @@ struct CORE_API RetrySettings {
8698
*/
8799
std::chrono::milliseconds connection_timeout = std::chrono::seconds(30);
88100

101+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
102+
/**
103+
* @brief Time allowed to wait for background connection to establish (in
104+
* milliseconds).
105+
*
106+
* The default value is 600 seconds.
107+
*
108+
* @note The value should be smaller than `timeout`, @see `timeout` for more
109+
* details.
110+
*/
111+
std::chrono::milliseconds background_connection_timeout =
112+
std::chrono::seconds(600);
113+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
114+
89115
/**
90116
* @brief Time allowed to wait without data transfer (in milliseconds).
91117
*

olp-cpp-sdk-core/include/olp/core/http/NetworkSettings.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2021 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -71,6 +71,15 @@ class CORE_API NetworkSettings final {
7171
*/
7272
std::chrono::milliseconds GetConnectionTimeoutDuration() const;
7373

74+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
75+
/**
76+
* @brief Gets the background connection timeout.
77+
*
78+
* @return The background connection timeout.
79+
*/
80+
std::chrono::milliseconds GetBackgroundConnectionTimeoutDuration() const;
81+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
82+
7483
/**
7584
* @brief Sets the connection timeout in seconds.
7685
*
@@ -92,6 +101,18 @@ class CORE_API NetworkSettings final {
92101
*/
93102
NetworkSettings& WithConnectionTimeout(std::chrono::milliseconds timeout);
94103

104+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
105+
/**
106+
* @brief Sets the background connection timeout.
107+
*
108+
* @param[in] timeout The background connection timeout.
109+
*
110+
* @return A reference to *this.
111+
*/
112+
NetworkSettings& WithBackgroundConnectionTimeout(
113+
std::chrono::milliseconds timeout);
114+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
115+
95116
/**
96117
* @brief Gets the transfer timeout in seconds.
97118
*
@@ -186,6 +207,11 @@ class CORE_API NetworkSettings final {
186207
std::size_t retries_{3};
187208
/// The connection timeout.
188209
std::chrono::milliseconds connection_timeout_ = std::chrono::seconds(60);
210+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
211+
/// The background connection timeout.
212+
std::chrono::milliseconds background_connection_timeout_ =
213+
std::chrono::seconds(600);
214+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
189215
/// The transfer timeout.
190216
std::chrono::milliseconds transfer_timeout_ = std::chrono::seconds(30);
191217
/// The max lifetime since creation allowed for reusing a connection.

olp-cpp-sdk-core/src/client/OlpClient.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
#include "olp/core/thread/Atomic.h"
3636
#include "olp/core/utils/Url.h"
3737

38+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
39+
#include "context/ContextInternal.h"
40+
#include "olp/core/context/EnterBackgroundSubscriber.h"
41+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
42+
3843
namespace {
3944
constexpr auto kLogTag = "OlpClient";
4045
constexpr auto kApiKeyParam = "apiKey=";
@@ -52,6 +57,75 @@ struct RequestSettings {
5257
std::chrono::milliseconds current_backdown_period{0};
5358
const std::chrono::milliseconds max_wait_time{0};
5459
};
60+
61+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
62+
class EnterBackgroundSubscriberImpl
63+
: public olp::context::EnterBackgroundSubscriber {
64+
public:
65+
struct Timeouts {
66+
std::chrono::seconds foreground_timeout{0};
67+
std::chrono::seconds background_timeout{0};
68+
};
69+
70+
void OnEnterBackground() override {
71+
std::lock_guard<std::mutex> lock(mutex_);
72+
in_background_ = true;
73+
std::for_each(states_.begin(), states_.end(),
74+
[&](bool value) { value = true; });
75+
}
76+
77+
void OnExitBackground() override {
78+
std::lock_guard<std::mutex> lock(mutex_);
79+
in_background_ = false;
80+
}
81+
82+
bool Wait(olp::client::Condition& client_condition, Timeouts timeouts) {
83+
std::list<bool>::iterator state_itr;
84+
85+
auto init_state = [&]() -> bool {
86+
std::lock_guard<std::mutex> lock(mutex_);
87+
state_itr = states_.insert(states_.end(), in_background_);
88+
return in_background_;
89+
};
90+
91+
auto pop_state = [&]() -> bool {
92+
std::lock_guard<std::mutex> lock(mutex_);
93+
bool state = *state_itr;
94+
states_.erase(state_itr);
95+
return state;
96+
};
97+
98+
const bool started_in_background = init_state();
99+
const auto condition_triggered = client_condition.Wait(
100+
started_in_background ? timeouts.background_timeout
101+
: timeouts.foreground_timeout);
102+
103+
const bool stored_state = pop_state();
104+
if ((condition_triggered &&
105+
(started_in_background || started_in_background == stored_state)) ||
106+
timeouts.background_timeout <= timeouts.foreground_timeout) {
107+
return condition_triggered;
108+
}
109+
110+
return client_condition.Wait(timeouts.background_timeout -
111+
timeouts.foreground_timeout);
112+
}
113+
114+
private:
115+
std::mutex mutex_;
116+
bool in_background_ = false;
117+
std::list<bool> states_;
118+
};
119+
120+
static std::shared_ptr<EnterBackgroundSubscriberImpl> gBackgroundSubscriber =
121+
[]() {
122+
auto impl = std::make_shared<EnterBackgroundSubscriberImpl>();
123+
olp::context::ContextInternal::SubscribeEnterBackground(impl);
124+
return impl;
125+
}();
126+
127+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
128+
55129
} // namespace
56130

57131
namespace olp {
@@ -285,6 +359,10 @@ HttpResponse SendRequest(const http::NetworkRequest& request,
285359

286360
http::SendOutcome outcome{http::ErrorCode::CANCELLED_ERROR};
287361
const auto timeout = std::chrono::seconds(retry_settings.timeout);
362+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
363+
const auto background_timeout =
364+
std::chrono::seconds(retry_settings.background_timeout);
365+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
288366

289367
context.ExecuteOrCancelled(
290368
[&]() {
@@ -321,7 +399,14 @@ HttpResponse SendRequest(const http::NetworkRequest& request,
321399
return ToHttpResponse(outcome);
322400
}
323401

402+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
403+
auto backgroundSubscriber = gBackgroundSubscriber;
404+
const auto condition_triggered = backgroundSubscriber->Wait(
405+
response_data->condition, {timeout, background_timeout});
406+
#else
324407
const auto condition_triggered = response_data->condition.Wait(timeout);
408+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
409+
325410
if (!condition_triggered) {
326411
OLP_SDK_LOG_WARNING_F(
327412
kLogTag,
@@ -605,6 +690,10 @@ CancellationToken OlpClient::OlpClientImpl::CallApi(
605690
network_request->WithSettings(
606691
http::NetworkSettings()
607692
.WithConnectionTimeout(retry_settings.connection_timeout)
693+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
694+
.WithBackgroundConnectionTimeout(
695+
retry_settings.background_connection_timeout)
696+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
608697
.WithTransferTimeout(retry_settings.transfer_timeout)
609698
.WithProxySettings(std::move(proxy)));
610699

@@ -642,6 +731,10 @@ HttpResponse OlpClient::OlpClientImpl::CallApi(
642731
http::NetworkSettings()
643732
.WithTransferTimeout(retry_settings.transfer_timeout)
644733
.WithConnectionTimeout(retry_settings.connection_timeout)
734+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
735+
.WithBackgroundConnectionTimeout(
736+
retry_settings.background_connection_timeout)
737+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
645738
.WithProxySettings(
646739
settings_.proxy_settings.value_or(http::NetworkProxySettings()));
647740

olp-cpp-sdk-core/src/http/NetworkSettings.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,13 @@ std::chrono::milliseconds NetworkSettings::GetConnectionTimeoutDuration()
3535
return connection_timeout_;
3636
}
3737

38+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
39+
std::chrono::milliseconds
40+
NetworkSettings::GetBackgroundConnectionTimeoutDuration() const {
41+
return background_connection_timeout_;
42+
}
43+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
44+
3845
int NetworkSettings::GetTransferTimeout() const {
3946
return static_cast<int>(std::chrono::duration_cast<std::chrono::seconds>(
4047
GetTransferTimeoutDuration())
@@ -72,6 +79,14 @@ NetworkSettings& NetworkSettings::WithConnectionTimeout(
7279
return *this;
7380
}
7481

82+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
83+
NetworkSettings& NetworkSettings::WithBackgroundConnectionTimeout(
84+
std::chrono::milliseconds timeout) {
85+
background_connection_timeout_ = timeout;
86+
return *this;
87+
}
88+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
89+
7590
NetworkSettings& NetworkSettings::WithTransferTimeout(int timeout) {
7691
return WithTransferTimeout(std::chrono::seconds(timeout));
7792
}

olp-cpp-sdk-core/src/http/ios/OLPHttpTask.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2023 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -80,6 +80,10 @@ typedef void (^OLPHttpTaskCompletionHandler)(NSError* error,
8080

8181
@property(nonatomic) NSUInteger connectionTimeout;
8282

83+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
84+
@property(nonatomic) NSUInteger backgroundConnectionTimeout;
85+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
86+
8387
@property(nonatomic) std::shared_ptr<std::ostream> payload;
8488

8589
// Readonly

olp-cpp-sdk-core/src/http/ios/OLPHttpTask.mm

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2023 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@
2727

2828
namespace {
2929
constexpr auto kLogTag = "OLPHttpTask";
30-
constexpr auto kBackgroundTimeoutMultiplicator = 100u;
3130
} // namespace
3231

3332
#pragma mark - OLPHttpTaskResponseData
@@ -106,9 +105,11 @@ - (OLPHttpTaskStatus)restart {
106105
NSMutableURLRequest* request =
107106
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
108107
request.timeoutInterval = self.connectionTimeout;
108+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
109109
if (self.backgroundMode) {
110-
request.timeoutInterval *= kBackgroundTimeoutMultiplicator;
110+
request.timeoutInterval = self.backgroundConnectionTimeout;
111111
}
112+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
112113
request.HTTPMethod = self.HTTPMethod;
113114
if (self.body.length) {
114115
request.HTTPBody = self.body;

olp-cpp-sdk-core/src/http/ios/OLPNetworkIOS.mm

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2023 HERE Europe B.V.
2+
* Copyright (C) 2019-2024 HERE Europe B.V.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -181,6 +181,15 @@
181181
task.headers = ParseHeadersDictionaryFromRequest(request);
182182
task.responseData = [[OLPHttpTaskResponseData alloc] init];
183183

184+
#ifdef OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
185+
const auto backgroundConnectionTimeoutSeconds =
186+
std::chrono::duration_cast<std::chrono::seconds>(
187+
settings.GetBackgroundConnectionTimeoutDuration())
188+
.count();
189+
task.backgroundConnectionTimeout =
190+
static_cast<int>(backgroundConnectionTimeoutSeconds);
191+
#endif // OLP_SDK_NETWORK_IOS_BACKGROUND_DOWNLOAD
192+
184193
__weak OLPHttpTask* weak_task = task;
185194
auto requestId = task.requestId;
186195

0 commit comments

Comments
 (0)