Skip to content

Commit d0cf80d

Browse files
authored
Merge pull request #244 from arduino-libraries/exponential-retry
Implement exponential retry/back-off strategy to avoid router overloading.
2 parents e5a6256 + c543d14 commit d0cf80d

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

src/AIoTC_Config.h

+8
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,12 @@
134134
#define HAS_TCP
135135
#endif
136136

137+
/******************************************************************************
138+
* CONSTANTS
139+
******************************************************************************/
140+
141+
#define AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms (1000UL)
142+
#define AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms (32000UL)
143+
#define AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms (10000UL)
144+
137145
#endif /* ARDUINO_AIOTC_CONFIG_H_ */

src/ArduinoIoTCloudTCP.cpp

+21-12
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,6 @@
5353
extern RTC_HandleTypeDef RTCHandle;
5454
#endif
5555

56-
/******************************************************************************
57-
GLOBAL CONSTANTS
58-
******************************************************************************/
59-
60-
static const int TIMEOUT_FOR_LASTVALUES_SYNC = 10000;
61-
6256
/******************************************************************************
6357
LOCAL MODULE FUNCTIONS
6458
******************************************************************************/
@@ -74,7 +68,9 @@ extern "C" unsigned long getTime()
7468

7569
ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
7670
: _state{State::ConnectPhy}
77-
, _lastSyncRequestTickTime{0}
71+
, _next_connection_attempt_tick{0}
72+
, _last_connection_attempt_cnt{0}
73+
, _last_sync_request_tick{0}
7874
, _mqtt_data_buf{0}
7975
, _mqtt_data_len{0}
8076
, _mqtt_data_request_retransmit{false}
@@ -337,9 +333,13 @@ void ArduinoIoTCloudTCP::printDebugInfo()
337333
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectPhy()
338334
{
339335
if (_connection->check() == NetworkConnectionState::CONNECTED)
340-
return State::SyncTime;
341-
else
342-
return State::ConnectPhy;
336+
{
337+
bool const is_retry_attempt = (_last_connection_attempt_cnt > 0);
338+
if (!is_retry_attempt || (is_retry_attempt && (millis() > _next_connection_attempt_tick)))
339+
return State::SyncTime;
340+
}
341+
342+
return State::ConnectPhy;
343343
}
344344

345345
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SyncTime()
@@ -352,9 +352,18 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SyncTime()
352352
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
353353
{
354354
if (_mqttClient.connect(_brokerAddress.c_str(), _brokerPort))
355+
{
356+
_last_connection_attempt_cnt = 0;
355357
return State::SubscribeMqttTopics;
358+
}
359+
360+
_last_connection_attempt_cnt++;
361+
unsigned long reconnection_retry_delay = (1 << _last_connection_attempt_cnt) * AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms;
362+
reconnection_retry_delay = min(reconnection_retry_delay, static_cast<unsigned long>(AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms));
363+
_next_connection_attempt_tick = millis() + reconnection_retry_delay;
356364

357365
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not connect to %s:%d", __FUNCTION__, _brokerAddress.c_str(), _brokerPort);
366+
DEBUG_ERROR("ArduinoIoTCloudTCP::%s %d connection attempt at tick time %d", __FUNCTION__, _last_connection_attempt_cnt, _next_connection_attempt_tick);
358367
return State::ConnectPhy;
359368
}
360369

@@ -410,11 +419,11 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_RequestLastValues()
410419

411420
/* Check whether or not we need to send a new request. */
412421
unsigned long const now = millis();
413-
if ((now - _lastSyncRequestTickTime) > TIMEOUT_FOR_LASTVALUES_SYNC)
422+
if ((now - _last_sync_request_tick) > AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms)
414423
{
415424
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values requested", __FUNCTION__, now);
416425
requestLastValue();
417-
_lastSyncRequestTickTime = now;
426+
_last_sync_request_tick = now;
418427
}
419428

420429
return State::RequestLastValues;

src/ArduinoIoTCloudTCP.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
9696

9797
State _state;
9898

99-
int _lastSyncRequestTickTime;
99+
unsigned long _next_connection_attempt_tick;
100+
unsigned int _last_connection_attempt_cnt;
101+
unsigned long _last_sync_request_tick;
100102
String _brokerAddress;
101103
uint16_t _brokerPort;
102104
uint8_t _mqtt_data_buf[MQTT_TRANSMIT_BUFFER_SIZE];

src/utility/watchdog/Watchdog.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ void wifi_nina_feed_watchdog()
7272
{
7373
samd_watchdog_reset();
7474
}
75+
76+
void mkr_gsm_feed_watchdog()
77+
{
78+
samd_watchdog_reset();
79+
}
80+
81+
void mkr_nb_feed_watchdog()
82+
{
83+
samd_watchdog_reset();
84+
}
7585
#endif /* ARDUINO_ARCH_SAMD */
7686

7787
#ifdef ARDUINO_ARCH_MBED

0 commit comments

Comments
 (0)