Skip to content

Commit 9d3ec6e

Browse files
committed
feat: exp back-off for detached device polling
1 parent fbcf0ec commit 9d3ec6e

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/ArduinoIoTCloudNotecard.cpp

+34-7
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242
* CONSTANTS
4343
******************************************************************************/
4444

45+
static size_t const BACKOFF_BASE_MS = 60000; // 1 minute
46+
static uint32_t const BACKOFF_MAX_MS = 3600000; // 1 hour
4547
static size_t const CBOR_NOTE_MSG_MAX_SIZE = 255;
46-
static size_t const DEFAULT_READ_INTERVAL_MS = 1000;
47-
static size_t const FAILSAFE_READ_INTERVAL_MS = 10000;
48+
static size_t const DEFAULT_READ_INTERVAL_MS = 1000; // 1 second
49+
static size_t const FAILSAFE_READ_INTERVAL_MS = 10000; // 10 seconds
4850

4951
/******************************************************************************
5052
* LOCAL MODULE FUNCTIONS
@@ -71,6 +73,8 @@ ArduinoIoTCloudNotecard::ArduinoIoTCloudNotecard()
7173
,_message_stream(std::bind(&ArduinoIoTCloudNotecard::sendMessage, this, std::placeholders::_1))
7274
,_thing(&_message_stream)
7375
,_device(&_message_stream)
76+
,_backoff_multiplier{1}
77+
,_last_failed_attach_request_ms{0}
7478
,_notecard_last_read_ms{static_cast<uint32_t>(-DEFAULT_READ_INTERVAL_MS)}
7579
,_notecard_read_interval_ms{DEFAULT_READ_INTERVAL_MS}
7680
,_interrupt_pin{-1}
@@ -231,6 +235,18 @@ ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_Connected()
231235
/* Poll Notecard for new messages */
232236
pollNotecard();
233237

238+
/* Respect back-off */
239+
if (_last_failed_attach_request_ms) {
240+
const uint32_t backoff_ms = (BACKOFF_BASE_MS * _backoff_multiplier);
241+
if ((::millis() - _last_failed_attach_request_ms) < backoff_ms) {
242+
return State::Connected;
243+
} else {
244+
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s back-off expired.", __FUNCTION__);
245+
_backoff_multiplier <<= (BACKOFF_MAX_MS > backoff_ms);
246+
_last_failed_attach_request_ms = 0;
247+
}
248+
}
249+
234250
/* Call CloudDevice process to get configuration */
235251
_device.update();
236252

@@ -397,16 +413,26 @@ void ArduinoIoTCloudNotecard::processCommand(const uint8_t *buf, size_t len)
397413
String new_thing_id = String(command.thingUpdateCmd.params.thing_id);
398414

399415
if (!new_thing_id.length()) {
400-
/* Send message to device state machine to inform we have received a null thing-id */
416+
_last_failed_attach_request_ms = ::millis();
417+
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s received null Thing ID (current back-off: %u minute%s).", __FUNCTION__, _backoff_multiplier, ((_backoff_multiplier == 1) ? "" : "s"));
401418
_thing_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
419+
420+
/* Send message to device state machine to inform we have received a null thing-id */
402421
Message message;
403422
message = { DeviceRegisteredCmdId };
404423
_device.handleMessage(&message);
405424
} else {
425+
DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s resetting back-off variables", __FUNCTION__);
426+
/* Reset back-off variables */
427+
_backoff_multiplier = 1;
428+
_last_failed_attach_request_ms = 0;
429+
406430
if (_device.isAttached() && _thing_id != new_thing_id) {
431+
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s detaching Thing ID: %s", __FUNCTION__, _thing_id.c_str());
407432
detachThing();
408433
}
409434
if (!_device.isAttached()) {
435+
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s attaching Thing ID: %s", __FUNCTION__, new_thing_id.c_str());
410436
attachThing(new_thing_id);
411437
}
412438
}
@@ -441,10 +467,11 @@ void ArduinoIoTCloudNotecard::processCommand(const uint8_t *buf, size_t len)
441467
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
442468

443469
/*
444-
* NOTE: in this current version properties are not properly integrated with the new paradigm of
445-
* modeling the messages with C structs. The current CBOR library allocates an array in the heap
446-
* thus we need to delete it after decoding it with the old CBORDecoder
447-
*/
470+
* NOTE: In this current version properties are not properly integrated
471+
* with the new paradigm of modeling the messages with C structs. The
472+
* current CBOR library allocates an array in the heap thus we need to
473+
* delete it after decoding it with the old CBORDecoder
474+
*/
448475
free(command.lastValuesUpdateCmd.params.last_values);
449476
}
450477
break;

src/ArduinoIoTCloudNotecard.h

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class ArduinoIoTCloudNotecard : public ArduinoIoTCloudClass
8686
ArduinoCloudDevice _device;
8787

8888
// Notecard member variables
89+
uint32_t _backoff_multiplier;
90+
uint32_t _last_failed_attach_request_ms;
8991
uint32_t _notecard_last_read_ms;
9092
uint32_t _notecard_read_interval_ms;
9193
int _interrupt_pin;

0 commit comments

Comments
 (0)