Skip to content

Commit

Permalink
feat: exp back-off for detached device polling
Browse files Browse the repository at this point in the history
  • Loading branch information
zfields committed Jul 30, 2024
1 parent fbcf0ec commit 9d3ec6e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/ArduinoIoTCloudNotecard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@
* CONSTANTS
******************************************************************************/

static size_t const BACKOFF_BASE_MS = 60000; // 1 minute
static uint32_t const BACKOFF_MAX_MS = 3600000; // 1 hour
static size_t const CBOR_NOTE_MSG_MAX_SIZE = 255;
static size_t const DEFAULT_READ_INTERVAL_MS = 1000;
static size_t const FAILSAFE_READ_INTERVAL_MS = 10000;
static size_t const DEFAULT_READ_INTERVAL_MS = 1000; // 1 second
static size_t const FAILSAFE_READ_INTERVAL_MS = 10000; // 10 seconds

/******************************************************************************
* LOCAL MODULE FUNCTIONS
Expand All @@ -71,6 +73,8 @@ ArduinoIoTCloudNotecard::ArduinoIoTCloudNotecard()
,_message_stream(std::bind(&ArduinoIoTCloudNotecard::sendMessage, this, std::placeholders::_1))
,_thing(&_message_stream)
,_device(&_message_stream)
,_backoff_multiplier{1}
,_last_failed_attach_request_ms{0}
,_notecard_last_read_ms{static_cast<uint32_t>(-DEFAULT_READ_INTERVAL_MS)}
,_notecard_read_interval_ms{DEFAULT_READ_INTERVAL_MS}
,_interrupt_pin{-1}
Expand Down Expand Up @@ -231,6 +235,18 @@ ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_Connected()
/* Poll Notecard for new messages */
pollNotecard();

/* Respect back-off */
if (_last_failed_attach_request_ms) {
const uint32_t backoff_ms = (BACKOFF_BASE_MS * _backoff_multiplier);
if ((::millis() - _last_failed_attach_request_ms) < backoff_ms) {
return State::Connected;
} else {
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s back-off expired.", __FUNCTION__);
_backoff_multiplier <<= (BACKOFF_MAX_MS > backoff_ms);
_last_failed_attach_request_ms = 0;
}
}

/* Call CloudDevice process to get configuration */
_device.update();

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

if (!new_thing_id.length()) {
/* Send message to device state machine to inform we have received a null thing-id */
_last_failed_attach_request_ms = ::millis();
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s received null Thing ID (current back-off: %u minute%s).", __FUNCTION__, _backoff_multiplier, ((_backoff_multiplier == 1) ? "" : "s"));
_thing_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

/* Send message to device state machine to inform we have received a null thing-id */
Message message;
message = { DeviceRegisteredCmdId };
_device.handleMessage(&message);
} else {
DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s resetting back-off variables", __FUNCTION__);
/* Reset back-off variables */
_backoff_multiplier = 1;
_last_failed_attach_request_ms = 0;

if (_device.isAttached() && _thing_id != new_thing_id) {
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s detaching Thing ID: %s", __FUNCTION__, _thing_id.c_str());
detachThing();
}
if (!_device.isAttached()) {
DEBUG_DEBUG("ArduinoIoTCloudNotecard::%s attaching Thing ID: %s", __FUNCTION__, new_thing_id.c_str());
attachThing(new_thing_id);
}
}
Expand Down Expand Up @@ -441,10 +467,11 @@ void ArduinoIoTCloudNotecard::processCommand(const uint8_t *buf, size_t len)
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);

/*
* NOTE: in this current version properties are not properly integrated with the new paradigm of
* modeling the messages with C structs. The current CBOR library allocates an array in the heap
* thus we need to delete it after decoding it with the old CBORDecoder
*/
* NOTE: In this current version properties are not properly integrated
* with the new paradigm of modeling the messages with C structs. The
* current CBOR library allocates an array in the heap thus we need to
* delete it after decoding it with the old CBORDecoder
*/
free(command.lastValuesUpdateCmd.params.last_values);
}
break;
Expand Down
2 changes: 2 additions & 0 deletions src/ArduinoIoTCloudNotecard.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class ArduinoIoTCloudNotecard : public ArduinoIoTCloudClass
ArduinoCloudDevice _device;

// Notecard member variables
uint32_t _backoff_multiplier;
uint32_t _last_failed_attach_request_ms;
uint32_t _notecard_last_read_ms;
uint32_t _notecard_read_interval_ms;
int _interrupt_pin;
Expand Down

0 comments on commit 9d3ec6e

Please sign in to comment.