From 47868d7c57947bc42e09d6bda77cd31b21263ea7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 27 Aug 2016 16:34:39 -0700 Subject: [PATCH] Centralize polling algorithm --- static/js/index.js | 76 +++++++++++++++++++++++++--------------------- static/js/utils.js | 65 ++++++++++++++++++++++++++++----------- 2 files changed, 89 insertions(+), 52 deletions(-) diff --git a/static/js/index.js b/static/js/index.js index 6c4dd2e..59e0ff8 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -58,37 +58,52 @@ function restoreUiAfterNaClLoad() { } function beginBackgroundPollingOfHost(host) { - $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); - // for each host, first assume it's inactive. - - host.initialPing(function () { // initial attempt was a success + if (host.online) { $("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive'); + + // The host was already online. Just start polling in the background now. activePolls[host.serverUid] = window.setInterval(function() { if (api && activePolls[api.serverUid] != null) { stopBackgroundPollingOfHost(api); return; } // every 5 seconds, poll at the address we know it was live at - host.refreshServerInfoAtAddress(host.address).then(function (onSuccess){ - $("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive'); - }, function (onFailure) { - $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); + host.pollServer(function () { + if (host.online) { + $("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive'); + } else { + $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); + } }); }, 5000); - }, function () { // initial attempt was a failure + } else { $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); - activePolls[host.serverUid] = window.setInterval(function() { - if (api && activePolls[api.serverUid] != null) { - stopBackgroundPollingOfHost(api); - return; - } - if(host.refreshServerInfoAtAddress(host.address)) { + + // The host was offline, so poll immediately. + host.pollServer(function () { + if (host.online) { $("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive'); } else { $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); } - }, 5000); - }); + + // Now start background polling + activePolls[host.serverUid] = window.setInterval(function() { + if (api && activePolls[api.serverUid] != null) { + stopBackgroundPollingOfHost(api); + return; + } + // every 5 seconds, poll at the address we know it was live at + host.pollServer(function () { + if (host.online) { + $("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive'); + } else { + $("#hostgrid-" + host.serverUid).addClass('host-cell-inactive'); + } + }); + }, 5000); + }); + } } function stopBackgroundPollingOfHost(host) { @@ -221,26 +236,17 @@ function hostChosen(sourceEvent) { } api = hosts[serverUid]; + if (!api.online) { + return; + } + stopBackgroundPollingOfHost(api); - // Use the cached state of this host from the last poll - if(!api.paired) { - // It doesn't think we're paired. Refresh our serverinfo to make sure. - api.refreshServerInfo().then(function (ret) { - if (!api.paired) { - // Still not paired; go to the pairing flow - pairTo(api, function(){ showApps(api); saveHosts();}, function(){}); - } else { - // When we queried again, it was paired, so show apps. - showApps(api); - } - }, function (failedRefreshInfo) { - snackbarLog('Failed to connect to ' + api.address + '! Are you sure the host is on?'); - console.log('Returned error was: ' + failedRefreshInfo); - console.log('failed API object: '); - console.log(api.toString()); - }); + if (!api.paired) { + // Still not paired; go to the pairing flow + pairTo(api, function(){ showApps(api); saveHosts();}, function(){}); } else { + // When we queried again, it was paired, so show apps. showApps(api); } } @@ -743,7 +749,7 @@ function onWindowLoad(){ var mDnsDiscoveredHost = new NvHTTP(ip, myUniqueid); if(hosts[mDnsDiscoveredHost.serverUid] != null) { // if we're seeing a host we've already seen before, update it for the current local IP. - hosts[mDnsDiscoveredHost.serverUid].localIp = mDnsDiscoveredHost.localIp; + hosts[mDnsDiscoveredHost.serverUid].address = mDnsDiscoveredHost.address; } else { addHostToGrid(mDnsDiscoveredHost); } diff --git a/static/js/utils.js b/static/js/utils.js index 9db12ae..8bbe34b 100644 --- a/static/js/utils.js +++ b/static/js/utils.js @@ -38,9 +38,10 @@ function NvHTTP(address, clientUid, userEnteredAddress = '') { this.currentGame = 0; this.serverMajorVersion = 0; this.clientUid = clientUid; - this._baseUrlHttps = 'https://' + address + ':47984'; - this._baseUrlHttp = 'http://' + address + ':47989'; this._memCachedBoxArtArray = {}; + this._pollCount = 0; + this._consecutivePollFailures = 0; + this.online = false; this.userEnteredAddress = userEnteredAddress; // if the user entered an address, we keep it on hand to try when polling this.serverUid = ''; @@ -100,22 +101,52 @@ NvHTTP.prototype = { }.bind(this)); }, + // called every few seconds to poll the server for updated info + pollServer: function(onComplete) { + this.selectServerAddress(function(successfulAddress) { + // Successfully determined server address. Update base URL. + this.address = successfulAddress; + this._baseUrlHttps = 'https://' + successfulAddress + ':47984'; + this._baseUrlHttp = 'http://' + successfulAddress + ':47989'; + + // Poll for the app list every 10 successful serverinfo polls. + // Not including the first one to avoid PCs taking a while to show + // as online initially + if (++this._pollCount % 10 == 0) { + this.getAppListWithCacheFlush(); + } + + this._consecutivePollFailures = 0; + this.online = true; + + onComplete(); + }.bind(this), function() { + if (++this._consecutivePollFailures >= 3) { + this.online = false; + } + + onComplete(); + }.bind(this)); + }, + // initially pings the server to try and figure out if it's routable by any means. - initialPing: function(onSuccess, onFailure) { - this.refreshServerInfoAtAddress(this.hostname + '.local').then(function(successLocal) { - this.address = this.hostname + '.local'; - onSuccess(); - }.bind(this), function(failureLocal) { - this.refreshServerInfoAtAddress(this.externalIP).then(function(successExternal) { - this.address = this.externalIP; - onSuccess(); - }.bind(this), function(failureExternal) { - this.refreshServerInfoAtAddress(this.userEnteredAddress).then(function(successUserEntered) { - this.address = this.userEnteredAddress; - onSuccess(); - }.bind(this), function(failureUserEntered) { - console.log('WARN! Failed to contact host: ' + this.hostname + '\r\n' + this.toString()); - onFailure(); + selectServerAddress: function(onSuccess, onFailure) { + // TODO: Deduplicate the addresses + this.refreshServerInfoAtAddress(this.address).then(function(successPrevAddr) { + onSuccess(this.address); + }.bind(this), function(successPrevAddr) { + this.refreshServerInfoAtAddress(this.hostname + '.local').then(function(successLocal) { + onSuccess(this.hostname + '.local'); + }.bind(this), function(failureLocal) { + this.refreshServerInfoAtAddress(this.externalIP).then(function(successExternal) { + onSuccess(this.externalIP); + }.bind(this), function(failureExternal) { + this.refreshServerInfoAtAddress(this.userEnteredAddress).then(function(successUserEntered) { + onSuccess(this.userEnteredAddress); + }.bind(this), function(failureUserEntered) { + console.log('WARN! Failed to contact host: ' + this.hostname + '\r\n' + this.toString()); + onFailure(); + }.bind(this)); }.bind(this)); }.bind(this)); }.bind(this));