From cf1da6a22d1494655a67e56bf1f253a96c432728 Mon Sep 17 00:00:00 2001 From: Gus Class Date: Thu, 4 Jan 2018 17:33:50 -0800 Subject: [PATCH 1/2] Adds backoff / retry to HTTP calls. --- iot/http_example/cloudiot_http_example.js | 44 +++++++++++++++++++++-- iot/http_example/package.json | 6 ++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/iot/http_example/cloudiot_http_example.js b/iot/http_example/cloudiot_http_example.js index b3907aacd7..73c4f00040 100644 --- a/iot/http_example/cloudiot_http_example.js +++ b/iot/http_example/cloudiot_http_example.js @@ -17,7 +17,7 @@ // [START iot_http_includes] const fs = require('fs'); const jwt = require('jsonwebtoken'); -const request = require('request'); +const request = require('requestretry'); // [END iot_http_includes] console.log('Google Cloud IoT Core HTTP example.'); @@ -141,6 +141,21 @@ function publishAsync (authToken, messageCount, numMessages) { binary_data: binaryData } }; + + // Custom backoff functions + function retryNotSuccess (err, response, body) { + if (err || response.statusCode !== 200) { + console.log(`Retrying publish on error: ${response.statusCode}`); + } + return response.statusCode !== 200; + } + function exponentialDelay (err, response, body) { + if (err) { + // No need to report again here. + } + return Math.floor(Math.random() * (3500 - 500 + 1) + 500); + } + const options = { url: url, headers: { @@ -148,9 +163,13 @@ function publishAsync (authToken, messageCount, numMessages) { 'content-type': 'application/json', 'cache-control': 'no-cache' }, + body: postData, + delayStrategy: exponentialDelay, json: true, - body: postData + maxAttempts: 5, + retryStrategy: retryNotSuccess }; + // Send events for high-frequency updates, update state only occasionally. const delayMs = argv.messageType === 'events' ? 1000 : 2000; request.post(options, function (error, response, body) { @@ -182,6 +201,21 @@ function publishAsync (authToken, messageCount, numMessages) { // [START iot_http_getconfig] function getConfig (authToken, version) { console.log(`Getting config from URL: ${urlBase}`); + + // Custom backoff functions + function retryNotSuccess (err, response, body) { + if (err || response.statusCode !== 200) { + console.log(`Retrying get config on error: ${response.statusCode}`); + } + return response.statusCode !== 200; + } + function exponentialDelay (err, response, body) { + if (err) { + // Reported in retry. + } + return Math.floor(Math.random() * (3500 - 500 + 1) + 500); + } + const options = { url: urlBase + '/config?local_version=' + version, headers: { @@ -190,8 +224,12 @@ function getConfig (authToken, version) { 'cache-control': 'no-cache' }, - json: true + json: true, + maxAttempts: 5, + retryStrategy: retryNotSuccess, + delayStrategy: exponentialDelay }; + console.log(JSON.stringify(request.RetryStrategies)); request.get(options, function (error, response, body) { if (error) { console.error('Received error: ', error); diff --git a/iot/http_example/package.json b/iot/http_example/package.json index a1aab57597..7454d58aa9 100644 --- a/iot/http_example/package.json +++ b/iot/http_example/package.json @@ -14,10 +14,10 @@ "@google-cloud/pubsub": "0.13.2", "@google-cloud/nodejs-repo-tools": "1.4.17", "ava": "0.22.0", - "yargs": "8.0.2", "jsonwebtoken": "7.4.1", - "request": "2.82.0", - "uuid": "3.1.0" + "requestretry": "requestretry", + "uuid": "3.1.0", + "yargs": "8.0.2" }, "testDependencies": { }, From d3a9fb8c753e7f6e896d963874ce58e725f12c0e Mon Sep 17 00:00:00 2001 From: Gus Class Date: Fri, 5 Jan 2018 12:18:38 -0800 Subject: [PATCH 2/2] Switches request library from requestretry to retry-request. --- iot/http_example/cloudiot_http_example.js | 53 +++++++---------------- iot/http_example/package.json | 2 +- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/iot/http_example/cloudiot_http_example.js b/iot/http_example/cloudiot_http_example.js index 73c4f00040..27b9a4d635 100644 --- a/iot/http_example/cloudiot_http_example.js +++ b/iot/http_example/cloudiot_http_example.js @@ -17,7 +17,7 @@ // [START iot_http_includes] const fs = require('fs'); const jwt = require('jsonwebtoken'); -const request = require('requestretry'); +const request = require('retry-request'); // [END iot_http_includes] console.log('Google Cloud IoT Core HTTP example.'); @@ -142,20 +142,6 @@ function publishAsync (authToken, messageCount, numMessages) { } }; - // Custom backoff functions - function retryNotSuccess (err, response, body) { - if (err || response.statusCode !== 200) { - console.log(`Retrying publish on error: ${response.statusCode}`); - } - return response.statusCode !== 200; - } - function exponentialDelay (err, response, body) { - if (err) { - // No need to report again here. - } - return Math.floor(Math.random() * (3500 - 500 + 1) + 500); - } - const options = { url: url, headers: { @@ -164,15 +150,19 @@ function publishAsync (authToken, messageCount, numMessages) { 'cache-control': 'no-cache' }, body: postData, - delayStrategy: exponentialDelay, json: true, - maxAttempts: 5, - retryStrategy: retryNotSuccess + method: 'POST', + retries: 5, + shouldRetryFn: + function (incomingHttpMessage) { + return incomingHttpMessage.statusMessage !== 'OK'; + } }; // Send events for high-frequency updates, update state only occasionally. const delayMs = argv.messageType === 'events' ? 1000 : 2000; - request.post(options, function (error, response, body) { + console.log(JSON.stringify(request)); + request(options, function (error, response, body) { if (error) { console.error('Received error: ', error); } else if (response.body.error) { @@ -202,20 +192,6 @@ function publishAsync (authToken, messageCount, numMessages) { function getConfig (authToken, version) { console.log(`Getting config from URL: ${urlBase}`); - // Custom backoff functions - function retryNotSuccess (err, response, body) { - if (err || response.statusCode !== 200) { - console.log(`Retrying get config on error: ${response.statusCode}`); - } - return response.statusCode !== 200; - } - function exponentialDelay (err, response, body) { - if (err) { - // Reported in retry. - } - return Math.floor(Math.random() * (3500 - 500 + 1) + 500); - } - const options = { url: urlBase + '/config?local_version=' + version, headers: { @@ -225,12 +201,15 @@ function getConfig (authToken, version) { }, json: true, - maxAttempts: 5, - retryStrategy: retryNotSuccess, - delayStrategy: exponentialDelay + retries: 5, + shouldRetryFn: + function (incomingHttpMessage) { + console.log('Retry?'); + return incomingHttpMessage.statusMessage !== 'OK'; + } }; console.log(JSON.stringify(request.RetryStrategies)); - request.get(options, function (error, response, body) { + request(options, function (error, response, body) { if (error) { console.error('Received error: ', error); } else if (response.body.error) { diff --git a/iot/http_example/package.json b/iot/http_example/package.json index 7454d58aa9..2da4f72d29 100644 --- a/iot/http_example/package.json +++ b/iot/http_example/package.json @@ -15,7 +15,7 @@ "@google-cloud/nodejs-repo-tools": "1.4.17", "ava": "0.22.0", "jsonwebtoken": "7.4.1", - "requestretry": "requestretry", + "retry-request": "3.3.1", "uuid": "3.1.0", "yargs": "8.0.2" },