@@ -123,6 +123,70 @@ bool NoteRequest(J *req)
123
123
return success ;
124
124
}
125
125
126
+ /**************************************************************************/
127
+ /*!
128
+ @brief Send a request to the Notecard.
129
+ Frees the request structure from memory after sending the request.
130
+ Retries the request for up to the specified timeoutSeconds if there is
131
+ no response, or if the response indicates an io error.
132
+ @param req
133
+ The `J` cJSON request object.
134
+ timeoutSeconds
135
+ Upper limit for retries if there is no response, or if the
136
+ response contains an io error.
137
+ @returns a boolean. Returns `true` if successful or `false` if an error
138
+ occurs, such as an out-of-memory or if an error was returned from
139
+ the transaction in the c_err field.
140
+ */
141
+ /**************************************************************************/
142
+ bool NoteRequestWithRetry (J * req , uint32_t timeoutSeconds )
143
+ {
144
+ // Exit if null request. This allows safe execution of the form NoteRequest(NoteNewRequest("xxx"))
145
+ if (req == NULL ) {
146
+ return false;
147
+ }
148
+
149
+ J * rsp ;
150
+
151
+ // Calculate expiry time in milliseconds
152
+ uint32_t expiresMs = _GetMs () + (timeoutSeconds * 1000 );
153
+
154
+ while (true) {
155
+ // Execute the transaction
156
+ rsp = NoteTransaction (req );
157
+
158
+ // Loop if there is no response, or if there is an io error
159
+ if ( (rsp == NULL ) || JContainsString (rsp , c_err , c_ioerr )) {
160
+
161
+ // Free error response
162
+ if (rsp != NULL ) {
163
+ JDelete (rsp );
164
+ }
165
+ } else {
166
+
167
+ // Exit loop on non-null response without io error
168
+ break ;
169
+ }
170
+
171
+ // Exit loop on timeout
172
+ if (_GetMs () >= expiresMs ) {
173
+ break ;
174
+ }
175
+ }
176
+
177
+ // Free the request
178
+ JDelete (req );
179
+
180
+ // If there is no response return false
181
+ if (rsp == NULL ) {
182
+ return false;
183
+ }
184
+ // Check for a transaction error, and exit
185
+ bool success = JIsNullString (rsp , c_err );
186
+ JDelete (rsp );
187
+ return success ;
188
+ }
189
+
126
190
/**************************************************************************/
127
191
/*!
128
192
@brief Send a request to the Notecard and return the response.
@@ -150,6 +214,67 @@ J *NoteRequestResponse(J *req)
150
214
return rsp ;
151
215
}
152
216
217
+ /**************************************************************************/
218
+ /*!
219
+ @brief Send a request to the Notecard and return the response.
220
+ Frees the request structure from memory after sending the request.
221
+ Retries the request for up to the specified timeoutSeconds if there is
222
+ no response, or if the response indicates an io error.
223
+ @param req
224
+ The `J` cJSON request object.
225
+ timeoutSeconds
226
+ Upper limit for retries if there is no response, or if the
227
+ response contains an io error.
228
+ @returns a `J` cJSON object with the response, or NULL if there is
229
+ insufficient memory.
230
+ */
231
+ /**************************************************************************/
232
+ J * NoteRequestResponseWithRetry (J * req , uint32_t timeoutSeconds )
233
+ {
234
+ // Exit if null request. This allows safe execution of the form NoteRequestResponse(NoteNewRequest("xxx"))
235
+ if (req == NULL ) {
236
+ return NULL ;
237
+ }
238
+
239
+ J * rsp ;
240
+
241
+ // Calculate expiry time in milliseconds
242
+ uint32_t expiresMs = _GetMs () + (timeoutSeconds * 1000 );
243
+
244
+ while (true) {
245
+ // Execute the transaction
246
+ rsp = NoteTransaction (req );
247
+
248
+ // Loop if there is no response, or if there is an io error
249
+ if ( (rsp == NULL ) || JContainsString (rsp , c_err , c_ioerr )) {
250
+
251
+ // Free error response
252
+ if (rsp != NULL ) {
253
+ JDelete (rsp );
254
+ }
255
+ } else {
256
+
257
+ // Exit loop on non-null response without io error
258
+ break ;
259
+ }
260
+
261
+ // Exit loop on timeout
262
+ if (_GetMs () >= expiresMs ) {
263
+ break ;
264
+ }
265
+ }
266
+
267
+ // Free the request
268
+ JDelete (req );
269
+
270
+ if (rsp == NULL ) {
271
+ return NULL ;
272
+ }
273
+
274
+ // Return the response
275
+ return rsp ;
276
+ }
277
+
153
278
/**************************************************************************/
154
279
/*!
155
280
@brief Given a JSON string, send a request to the Notecard.
@@ -264,7 +389,7 @@ J *NoteTransaction(J *req)
264
389
_Debug ("invalid JSON: " );
265
390
_Debug (responseJSON );
266
391
_Free (responseJSON );
267
- J * rsp = errDoc (ERRSTR ("unrecognized response from card" , c_bad ));
392
+ J * rsp = errDoc (ERRSTR ("unrecognized response from card {io}" , c_iobad ));
268
393
_UnlockNote ();
269
394
return rsp ;
270
395
}
0 commit comments