Bug 781952 - Part 2: Move cluster management out of service.js; r=rnewman

This commit is contained in:
Gregory Szorc 2012-08-14 11:34:20 -07:00
parent 2b7e5b1f01
commit 766a2d965e
5 changed files with 112 additions and 68 deletions

View File

@ -57,6 +57,7 @@ sync_engine_modules := \
$(NULL)
sync_stage_modules := \
cluster.js \
enginesync.js \
$(NULL)

View File

@ -34,6 +34,7 @@ Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/stages/cluster.js");
Cu.import("resource://services-sync/stages/enginesync.js");
const STORAGE_INFO_TYPES = [INFO_COLLECTIONS,
@ -294,6 +295,8 @@ WeaveSvc.prototype = {
this._log.info("Loading Weave " + WEAVE_VERSION);
this._clusterManager = new ClusterManager(this);
this.enabled = true;
this._registerEngines();
@ -423,61 +426,6 @@ WeaveSvc.prototype = {
}
},
// gets cluster from central LDAP server and returns it, or null on error
_findCluster: function _findCluster() {
this._log.debug("Finding cluster for user " + this._identity.username);
let fail;
let res = new Resource(this.userAPI + this._identity.username + "/node/weave");
try {
let node = res.get();
switch (node.status) {
case 400:
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
fail = "Find cluster denied: " + ErrorHandler.errorStr(node);
break;
case 404:
this._log.debug("Using serverURL as data cluster (multi-cluster support disabled)");
return this.serverURL;
case 0:
case 200:
if (node == "null") {
node = null;
}
this._log.trace("_findCluster successfully returning " + node);
return node;
default:
ErrorHandler.checkServerError(node);
fail = "Unexpected response code: " + node.status;
break;
}
} catch (e) {
this._log.debug("Network error on findCluster");
Status.login = LOGIN_FAILED_NETWORK_ERROR;
ErrorHandler.checkServerError(e);
fail = e;
}
throw fail;
},
// gets cluster from central LDAP server and sets this.clusterURL
_setCluster: function _setCluster() {
// Make sure we didn't get some unexpected response for the cluster
let cluster = this._findCluster();
this._log.debug("Cluster value = " + cluster);
if (cluster == null)
return false;
// Don't update stuff if we already have the right cluster
if (cluster == this.clusterURL)
return false;
this._log.debug("Setting cluster to " + cluster);
this.clusterURL = cluster;
Svc.Prefs.set("lastClusterUpdate", Date.now().toString());
return true;
},
// Update cluster if required.
// Returns false if the update was not required.
_updateCluster: function _updateCluster() {
@ -485,7 +433,7 @@ WeaveSvc.prototype = {
let cTime = Date.now();
let lastUp = parseFloat(Svc.Prefs.get("lastClusterUpdate"));
if (!lastUp || ((cTime - lastUp) >= CLUSTER_BACKOFF)) {
return this._setCluster();
return this._clusterManager.setCluster();
}
return false;
},
@ -655,7 +603,7 @@ WeaveSvc.prototype = {
// Make sure we have a cluster to verify against.
// This is a little weird, if we don't get a node we pretend
// to succeed, since that probably means we just don't have storage.
if (this.clusterURL == "" && !this._setCluster()) {
if (this.clusterURL == "" && !this._clusterManager.setCluster()) {
Status.sync = NO_SYNC_NODE_FOUND;
Svc.Obs.notify("weave:service:sync:delayed");
return true;
@ -695,7 +643,7 @@ WeaveSvc.prototype = {
case 404:
// Check that we're verifying with the correct cluster
if (this._setCluster()) {
if (this._clusterManager.setCluster()) {
return this.verifyLogin();
}

View File

@ -0,0 +1,95 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const EXPORTED_SYMBOLS = ["ClusterManager"];
const {utils: Cu} = Components;
Cu.import("resource://services-common/log4moz.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/resource.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/util.js");
/**
* Contains code for managing the Sync cluster we are in.
*/
function ClusterManager(service) {
this._log = Log4Moz.repository.getLogger("Sync.Service");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")];
this.service = service;
}
ClusterManager.prototype = {
get identity() {
return this.service._identity;
},
/**
* Obtain the cluster for the current user.
*
* Returns the string URL of the cluster or null on error.
*/
_findCluster: function _findCluster() {
this._log.debug("Finding cluster for user " + this.identity.username);
let fail;
let res = new Resource(this.service.userAPI + this.identity.username +
"/node/weave");
try {
let node = res.get();
switch (node.status) {
case 400:
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
fail = "Find cluster denied: " + ErrorHandler.errorStr(node);
break;
case 404:
this._log.debug("Using serverURL as data cluster (multi-cluster support disabled)");
return this.service.serverURL;
case 0:
case 200:
if (node == "null") {
node = null;
}
this._log.trace("_findCluster successfully returning " + node);
return node;
default:
ErrorHandler.checkServerError(node);
fail = "Unexpected response code: " + node.status;
break;
}
} catch (e) {
this._log.debug("Network error on findCluster");
Status.login = LOGIN_FAILED_NETWORK_ERROR;
ErrorHandler.checkServerError(e);
fail = e;
}
throw fail;
},
/**
* Determine the cluster for the current user and update state.
*/
setCluster: function setCluster() {
// Make sure we didn't get some unexpected response for the cluster.
let cluster = this._findCluster();
this._log.debug("Cluster value = " + cluster);
if (cluster == null) {
return false;
}
// Don't update stuff if we already have the right cluster
if (cluster == this.service.clusterURL) {
return false;
}
this._log.debug("Setting cluster to " + cluster);
this.service.clusterURL = cluster;
Svc.Prefs.set("lastClusterUpdate", Date.now().toString());
return true;
},
};
Object.freeze(ClusterManager.prototype);

View File

@ -59,7 +59,7 @@ EngineSynchronizer.prototype = {
}
// If we don't have a node, get one. If that fails, retry in 10 minutes.
if (this.service.clusterURL == "" && !this.service._setCluster()) {
if (!this.service.clusterURL && !this.service._clusterManager.setCluster()) {
Status.sync = NO_SYNC_NODE_FOUND;
this._log.info("No cluster URL found. Cannot sync.");
this.onComplete(null);

View File

@ -20,7 +20,7 @@ function test_findCluster() {
_("_findCluster() throws on network errors (e.g. connection refused).");
do_check_throws(function() {
Service._findCluster();
Service._clusterManager._findCluster();
});
server = httpd_setup({
@ -32,29 +32,29 @@ function test_findCluster() {
});
_("_findCluster() returns the user's cluster node");
let cluster = Service._findCluster();
let cluster = Service._clusterManager._findCluster();
do_check_eq(cluster, "http://weave.user.node/");
_("A 'null' response is converted to null.");
Identity.account = "jimdoe";
cluster = Service._findCluster();
cluster = Service._clusterManager._findCluster();
do_check_eq(cluster, null);
_("If a 404 is encountered, the server URL is taken as the cluster URL");
Identity.account = "janedoe";
cluster = Service._findCluster();
cluster = Service._clusterManager._findCluster();
do_check_eq(cluster, Service.serverURL);
_("A 400 response will throw an error.");
Identity.account = "juliadoe";
do_check_throws(function() {
Service._findCluster();
Service._clusterManager._findCluster();
});
_("Any other server response (e.g. 500) will throw an error.");
Identity.account = "joedoe";
do_check_throws(function() {
Service._findCluster();
Service._clusterManager._findCluster();
});
} finally {
@ -80,16 +80,16 @@ function test_setCluster() {
do_check_eq(Service.clusterURL, "");
_("Set the cluster URL.");
do_check_true(Service._setCluster());
do_check_true(Service._clusterManager.setCluster());
do_check_eq(Service.clusterURL, "http://weave.user.node/");
_("Setting it again won't make a difference if it's the same one.");
do_check_false(Service._setCluster());
do_check_false(Service._clusterManager.setCluster());
do_check_eq(Service.clusterURL, "http://weave.user.node/");
_("A 'null' response won't make a difference either.");
Identity.account = "jimdoe";
do_check_false(Service._setCluster());
do_check_false(Service._clusterManager.setCluster());
do_check_eq(Service.clusterURL, "http://weave.user.node/");
} finally {