From 3c11ac6cf57396fea9d95cf691ae47df1a820fae Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Sat, 8 Oct 2016 10:33:18 -0700 Subject: [PATCH] Add jitter and retry logic to google drive userscript lookups --- package.json | 2 +- player/gdrive-player.coffee | 36 ++++++++++++++++--------- player/update.coffee | 8 ------ www/js/player.js | 54 +++++++++++++++++++------------------ www/js/util.js | 31 +++++++++++++++++++++ 5 files changed, 84 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index d4389f43..9cbf6187 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "3.23.3", + "version": "3.23.4", "repository": { "url": "http://github.com/calzoneman/sync" }, diff --git a/player/gdrive-player.coffee b/player/gdrive-player.coffee index 1805d8fb..895424f4 100644 --- a/player/gdrive-player.coffee +++ b/player/gdrive-player.coffee @@ -6,18 +6,30 @@ window.GoogleDrivePlayer = class GoogleDrivePlayer extends VideoJSPlayer super(data) load: (data) -> - window.maybePromptToUpgradeUserscript() + if not window.hasDriveUserscript and not data.meta.direct + window.promptToInstallDriveUserscript() + else if window.hasDriveUserscript + window.maybePromptToUpgradeUserscript() if typeof window.getGoogleDriveMetadata is 'function' - window.getGoogleDriveMetadata(data.id, (error, metadata) => - if error - console.error(error) - alertBox = window.document.createElement('div') - alertBox.className = 'alert alert-danger' - alertBox.textContent = error - document.getElementById('ytapiplayer').appendChild(alertBox) - else - data.meta.direct = metadata.videoMap - super(data) - ) + setTimeout(=> + backoffRetry((cb) -> + window.getGoogleDriveMetadata(data.id, cb) + , (error, metadata) => + if error + console.error(error) + alertBox = window.document.createElement('div') + alertBox.className = 'alert alert-danger' + alertBox.textContent = error + document.getElementById('ytapiplayer').appendChild(alertBox) + else + data.meta.direct = metadata.videoMap + super(data) + , { + maxTries: 3 + delay: 1000 + factor: 1.2 + jitter: 500 + }) + , Math.random() * 1000) else super(data) diff --git a/player/update.coffee b/player/update.coffee index 44eeb99a..af81890f 100644 --- a/player/update.coffee +++ b/player/update.coffee @@ -31,14 +31,6 @@ window.loadMediaPlayer = (data) -> window.PLAYER = new VideoJSPlayer(data) catch e console.error e - else if data.type is 'gd' - try - if data.meta.html5hack or window.hasDriveUserscript - window.PLAYER = new GoogleDrivePlayer(data) - else - window.PLAYER = new GoogleDriveYouTubePlayer(data) - catch e - console.error e else if data.type of TYPE_MAP try window.PLAYER = TYPE_MAP[data.type](data) diff --git a/www/js/player.js b/www/js/player.js index 63694864..f38af96a 100644 --- a/www/js/player.js +++ b/www/js/player.js @@ -679,23 +679,36 @@ } GoogleDrivePlayer.prototype.load = function(data) { - window.maybePromptToUpgradeUserscript(); + if (!window.hasDriveUserscript && !data.meta.direct) { + window.promptToInstallDriveUserscript(); + } else if (window.hasDriveUserscript) { + window.maybePromptToUpgradeUserscript(); + } if (typeof window.getGoogleDriveMetadata === 'function') { - return window.getGoogleDriveMetadata(data.id, (function(_this) { - return function(error, metadata) { - var alertBox; - if (error) { - console.error(error); - alertBox = window.document.createElement('div'); - alertBox.className = 'alert alert-danger'; - alertBox.textContent = error; - return document.getElementById('ytapiplayer').appendChild(alertBox); - } else { - data.meta.direct = metadata.videoMap; - return GoogleDrivePlayer.__super__.load.call(_this, data); - } + return setTimeout((function(_this) { + return function() { + return backoffRetry(function(cb) { + return window.getGoogleDriveMetadata(data.id, cb); + }, function(error, metadata) { + var alertBox; + if (error) { + console.error(error); + alertBox = window.document.createElement('div'); + alertBox.className = 'alert alert-danger'; + alertBox.textContent = error; + return document.getElementById('ytapiplayer').appendChild(alertBox); + } else { + data.meta.direct = metadata.videoMap; + return GoogleDrivePlayer.__super__.load.call(_this, data); + } + }, { + maxTries: 3, + delay: 1000, + factor: 1.2, + jitter: 500 + }); }; - })(this)); + })(this), Math.random() * 1000); } else { return GoogleDrivePlayer.__super__.load.call(this, data); } @@ -1530,17 +1543,6 @@ e = error1; return console.error(e); } - } else if (data.type === 'gd') { - try { - if (data.meta.html5hack || window.hasDriveUserscript) { - return window.PLAYER = new GoogleDrivePlayer(data); - } else { - return window.PLAYER = new GoogleDriveYouTubePlayer(data); - } - } catch (error1) { - e = error1; - return console.error(e); - } } else if (data.type in TYPE_MAP) { try { return window.PLAYER = TYPE_MAP[data.type](data); diff --git a/www/js/util.js b/www/js/util.js index 9b806124..84125774 100644 --- a/www/js/util.js +++ b/www/js/util.js @@ -3256,3 +3256,34 @@ function maybePromptToUpgradeUserscript() { alertBox.insertBefore(closeButton, alertBox.firstChild) document.getElementById('videowrap').appendChild(alertBox); } + +function backoffRetry(fn, cb, options) { + var jitter = options.jitter || 0; + var factor = options.factor || 1; + var isRetryable = options.isRetryable || function () { return true; }; + var tries = 0; + + function callback(error, result) { + tries++; + factor *= factor; + if (error) { + if (tries >= options.maxTries) { + console.log('Max tries exceeded'); + cb(error, result); + } else if (isRetryable(error)) { + var offset = Math.random() * jitter; + var delay = options.delay * factor + offset; + console.log('Retrying on error: ' + error); + console.log('Waiting ' + delay + ' ms before retrying'); + + setTimeout(function () { + fn(callback); + }, delay); + } + } else { + cb(error, result); + } + } + + fn(callback); +}