diff --git a/README.md b/README.md index 98fc647..2562c2e 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ * `CARELINK_REQUEST_INTERVAL` - number of milliseconds to wait between requests to the CareLink server (default: 60000) * `CARELINK_SGV_LIMIT` - maximum number of recent sensor glucose values to send to Nightscout (default: 24) +* `CARELINK_MAX_RETRY_DURATION` - maximum number of seconds to spend retrying failed requests to CareLink, ideally a power of 2 (default: 512) * `NS` - a fully-qualified Nightscout URL (e.g. `https://sitename.azurewebsites.net`) which overrides `WEBSITE_HOSTNAME` ## Currently supported data diff --git a/carelink.js b/carelink.js index 166bb8a..3dc7b16 100644 --- a/carelink.js +++ b/carelink.js @@ -8,13 +8,15 @@ var common = require('common'), var logger = require('./logger'); +var DEFAULT_MAX_RETRY_DURATION = module.exports.defaultMaxRetryDuration = 512; + var CARELINK_SECURITY_URL = 'https://carelink.minimed.com/patient/j_security_check'; var CARELINK_AFTER_LOGIN_URL = 'https://carelink.minimed.com/patient/main/login.do'; +var CARELINK_JSON_BASE_URL = 'https://carelink.minimed.com/patient/connect/ConnectViewerServlet?cpSerialNumber=NONE&msgType=last24hours&requestTime='; var CARELINK_LOGIN_COOKIE = '_WL_AUTHCOOKIE_JSESSIONID'; -var MAX_RETRY_COUNT = 10; var carelinkJsonUrlNow = function() { - return 'https://carelink.minimed.com/patient/connect/ConnectViewerServlet?cpSerialNumber=NONE&msgType=last24hours&requestTime=' + Date.now(); + return CARELINK_JSON_BASE_URL + Date.now(); }; function reqOptions(extra) { @@ -55,6 +57,18 @@ function checkResponseThen(fn) { }; } +function retryDurationOnAttempt(n) { + return Math.pow(2, n); +} + +function totalDurationAfterNextRetry(n) { + var sum = 0; + for(var i = 0; i <= n; i++) { + sum += retryDurationOnAttempt(i); + } + return sum; +} + var Client = exports.Client = function (options) { if (!(this instanceof Client)) { return new Client(arguments[0]); @@ -62,6 +76,10 @@ var Client = exports.Client = function (options) { var jar = request.jar(); + if (options.maxRetryDuration === undefined) { + options.maxRetryDuration = DEFAULT_MAX_RETRY_DURATION; + } + function doLogin(next) { logger.log('POST ' + CARELINK_SECURITY_URL); request.post( @@ -94,11 +112,11 @@ var Client = exports.Client = function (options) { logger.log(err); if (retryCount === undefined ) { retryCount = 0; - } else if (retryCount >= MAX_RETRY_COUNT) { - logger.log('Retried too many times.'); + } else if (totalDurationAfterNextRetry(retryCount) >= options.maxRetryDuration) { + logger.log('Retried for too long (' + totalDurationAfterNextRetry(retryCount - 1) + ' seconds).'); next(err); } - var timeout = Math.pow(2, retryCount); + var timeout = retryDurationOnAttempt(retryCount); logger.log('Trying again in ' + timeout + ' second(s)...'); setTimeout(function() { getConnectData(response, next, retryCount + 1); diff --git a/run.js b/run.js index c88c10a..90d39d7 100644 --- a/run.js +++ b/run.js @@ -20,8 +20,9 @@ var config = { nsHost: readEnv('WEBSITE_HOSTNAME'), nsBaseUrl: readEnv('NS'), nsSecret: readEnv('API_SECRET'), - interval: parseInt(readEnv('CARELINK_REQUEST_INTERVAL', 60 * 1000)), - sgvLimit: parseInt(readEnv('CARELINK_SGV_LIMIT', 24)) + interval: parseInt(readEnv('CARELINK_REQUEST_INTERVAL', 60 * 1000), 10), + sgvLimit: parseInt(readEnv('CARELINK_SGV_LIMIT', 24), 10), + maxRetryDuration: parseInt(readEnv('CARELINK_MAX_RETRY_DURATION', carelink.defaultMaxRetryDuration), 10) }; if (!config.username) { @@ -30,7 +31,11 @@ if (!config.username) { throw new Error('Missing CareLink password'); } -var client = carelink.Client({username: config.username, password: config.password}); +var client = carelink.Client({ + username: config.username, + password: config.password, + maxRetryDuration: config.maxRetryDuration +}); var endpoint = (config.nsBaseUrl ? config.nsBaseUrl : 'https://' + config.nsHost) + '/api/v1/entries.json'; (function requestLoop() {