Skip to content

Commit

Permalink
This keeps backwards compatibility by converting params from seconds if
Browse files Browse the repository at this point in the history
they are less than 100 (minInterval) or 1000 (maxInterval).

This also makes the connectTimeout consistent with the reconnect interval params.

Signed-off-by: Dom Postorivo <[email protected]>
  • Loading branch information
dpostorivo committed Nov 21, 2023
1 parent 07a8757 commit 5d4121d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 20 deletions.
31 changes: 25 additions & 6 deletions src/MQTTAsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
m->connect.onFailure5 = options->onFailure5;
}
m->connect.context = options->context;
m->connectTimeout = options->connectTimeout;
m->connectTimeoutMs = options->connectTimeout * 1000;

/* don't lock async mutex if we are being called from a callback */
thread_id = Paho_thread_getid();
Expand Down Expand Up @@ -679,8 +679,27 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
if (options->struct_version >= 4)
{
m->automaticReconnect = options->automaticReconnect;
m->minRetryInterval = options->minRetryInterval;
m->maxRetryInterval = options->maxRetryInterval;
// Old retry time params were in seconds, but we want to support
// millisecond min retry intervals.
// To remain backwards compatible, if the param is under 100, we
// assume it's in seconds, otherwise, milliseconds.
if (options->minRetryInterval < 100)
{
m->minRetryIntervalMs = options->minRetryInterval * 1000;
}
else
{
m->minRetryIntervalMs = options->minRetryInterval;
}
// Similar for max interval, if it's under 1000, we assume seconds
if (options->maxRetryInterval < 1000)
{
m->maxRetryIntervalMs = options->maxRetryInterval * 1000;
}
else
{
m->maxRetryIntervalMs = options->maxRetryInterval;
}
}
if (options->struct_version >= 7)
{
Expand Down Expand Up @@ -847,7 +866,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
m->c->retryInterval = options->retryInterval;
m->shouldBeConnected = 1;

m->connectTimeout = options->connectTimeout;
m->connectTimeoutMs = options->connectTimeout * 1000;

MQTTAsync_freeServerURIs(m);
if (options->struct_version >= 2 && options->serverURIcount > 0)
Expand Down Expand Up @@ -949,8 +968,8 @@ int MQTTAsync_reconnect(MQTTAsync handle)
if (m->shouldBeConnected)
{
m->reconnectNow = 1;
m->currentIntervalBase = m->minRetryInterval;
m->currentInterval = m->minRetryInterval;
m->currentIntervalBaseMs = m->minRetryIntervalMs;
m->currentIntervalMs = m->minRetryIntervalMs;
m->retrying = 1;
rc = MQTTASYNC_SUCCESS;
}
Expand Down
19 changes: 16 additions & 3 deletions src/MQTTAsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,9 @@ typedef struct
const char* password;
/**
* The time interval in seconds to allow a connect to complete.
* The time interval in milliseconds to allow a connect to complete.
* For backwards compatibility and consistency with the retry intervals
* this is considered to be seconds if it is under 1000.
*/
int connectTimeout;
/**
Expand Down Expand Up @@ -1324,15 +1327,25 @@ typedef struct
*/
int MQTTVersion;
/**
* Reconnect automatically in the case of a connection being lost. 0=false, 1=true
* Reconnect automatically in the case of a connection being lost?
* This retries with exponential backoff starting from the minRetryInterval
* up to the maxRetryInterval, +/- 20% random jitter.
*/
int automaticReconnect;
/**
* The minimum automatic reconnect retry interval in seconds. Doubled on each failed retry.
* Minimum retry interval in milliseconds. Doubled on each failed retry.
* For backwards compatibility, if the value is under 100,
* it is assumed to be in seconds rather than milliseconds.
* Random jitter is applied to the value with +/- 20%
*/
int minRetryInterval;
/**
* The maximum automatic reconnect retry interval in seconds. The doubling stops here on failed retries.
* Maximum retry interval in milliseconds. The doubling stops here on failed retries.
* For backwards compatibility, if the value is under 1000,
* it is assumed to be in seconds rather than milliseconds.
* Note: due to random jitter, the actual max time interval could be as much as 20% higher,
* but this will change on each retry.
* e.g. for maxRetryInterval of 60 seconds, the actual wait time could be anywhere from 48 to 72 seconds
*/
int maxRetryInterval;
/**
Expand Down
10 changes: 5 additions & 5 deletions src/MQTTAsyncUtils.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,14 +923,14 @@ void MQTTAsync_startConnectRetry(MQTTAsyncs* m)
m->lastConnectionFailedTime = MQTTTime_start_clock();
if (m->retrying)
{
m->currentIntervalBase = min(m->currentIntervalBase * 2, m->maxRetryInterval);
m->currentIntervalBaseMs = min(m->currentIntervalBaseMs * 2, m->maxRetryIntervalMs);
}
else
{
m->currentIntervalBase = m->minRetryInterval;
m->currentIntervalBaseMs = m->minRetryIntervalMs;
m->retrying = 1;
}
m->currentInterval = MQTTAsync_randomJitter(m->currentIntervalBase, m->minRetryInterval, m->maxRetryInterval);
m->currentIntervalMs = MQTTAsync_randomJitter(m->currentIntervalBaseMs, m->minRetryIntervalMs, m->maxRetryIntervalMs);
}
}

Expand Down Expand Up @@ -1701,7 +1701,7 @@ static void MQTTAsync_checkTimeouts(void)
MQTTAsync_checkDisconnect(m, &m->disconnect);

/* check connect timeout */
if (m->c->connect_state != NOT_IN_PROGRESS && MQTTTime_elapsed(m->connect.start_time) > (ELAPSED_TIME_TYPE)(m->connectTimeout * 1000))
if (m->c->connect_state != NOT_IN_PROGRESS && MQTTTime_elapsed(m->connect.start_time) > (ELAPSED_TIME_TYPE)(m->connectTimeoutMs))
{
nextOrClose(m, MQTTASYNC_FAILURE, "TCP connect timeout");
continue;
Expand All @@ -1715,7 +1715,7 @@ static void MQTTAsync_checkTimeouts(void)

if (m->automaticReconnect && m->retrying)
{
if (m->reconnectNow || MQTTTime_elapsed(m->lastConnectionFailedTime) > (ELAPSED_TIME_TYPE)(m->currentInterval * 1000))
if (m->reconnectNow || MQTTTime_elapsed(m->lastConnectionFailedTime) > (ELAPSED_TIME_TYPE)(m->currentIntervalMs))
{
/* to reconnect put the connect command to the head of the command queue */
MQTTAsync_queuedCommand* conn = malloc(sizeof(MQTTAsync_queuedCommand));
Expand Down
12 changes: 6 additions & 6 deletions src/MQTTAsyncUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,16 @@ typedef struct MQTTAsync_struct
int shouldBeConnected;
int noBufferedMessages; /* the current number of buffered (publish) messages for this client */

/* added for automatic reconnect */
/* added for automatic reconnect, intervals are in MS */
int automaticReconnect;
int minRetryInterval;
int maxRetryInterval;
int minRetryIntervalMs;
int maxRetryIntervalMs;
int serverURIcount;
char** serverURIs;
int connectTimeout;
int connectTimeoutMs;

int currentInterval;
int currentIntervalBase;
int currentIntervalMs;
int currentIntervalBaseMs;
START_TIME_TYPE lastConnectionFailedTime;
int retrying;
int reconnectNow;
Expand Down

0 comments on commit 5d4121d

Please sign in to comment.