Use incrementing version to reconcile setting sync conflicts instead of timestamp

Skylar Ittner 2 years ago
parent 147c80302e
commit 18a49da6b0

@ -1,4 +1,4 @@
/*
/*
* 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/.
@ -9,7 +9,7 @@
* Save something to persistent storage.
* @param {string} key
* @param {string} value non-string values are converted to strings.
* @param {bool} nochangeupdate If true, the lastchange setting won't be updated.
* @param {bool} nochangeupdate If true, the settings version won't be updated.
* @returns {undefined}
*/
function setStorage(key, value, nochangeupdate) {
@ -18,7 +18,8 @@ function setStorage(key, value, nochangeupdate) {
}
localStorage.setItem(key, value);
if (!nochangeupdate && !SETTINGS.synckeyblacklist.includes(key)) {
localStorage.setItem("lastchange", Date.now() / 1000);
var version = getStorage("syncstateversion") == null ? 0 : getStorage("syncstateversion");
localStorage.setItem("syncstateversion", Number(version) + 1);
}
}

@ -6,15 +6,13 @@
function gatherSyncData() {
if (getStorage("syncstateversion") == null) {
setStorage("syncstateversion", 0);
}
var data = {
localStorage: {},
changed: getStorage("lastchange") == null ? 0 : getStorage("lastchange"),
stateversion: getStorage("syncstateversion") == null ? 0 : getStorage("syncstateversion")
};
if (!inStorage("lastsync")) {
// first time syncing to the server, let's make sure
// the server settings take precedence
data.changed = 1;
}
var allitems = getAllStorage();
for (var i = 0; i < allitems.length; i++) {
var key = allitems[i].key;
@ -27,33 +25,30 @@ function gatherSyncData() {
return data;
}
function syncDataToLocalStorage(data) {
function syncDataToLocalStorage(data, stateversion) {
for (var key in data.localStorage) {
if (data.localStorage.hasOwnProperty(key)) {
setStorage(key, data.localStorage[key], true);
}
}
setStorage("syncstateversion", stateversion);
}
function resolveSync(remotedata) {
var localchangetime = getStorage("lastchange");
if (remotedata.changed == null) {
// The server has nothing, this is the first sync
return true;
}
if (localchangetime == null) {
// No local setting changes but since we've gotten this far,
// the server has stuff for us
syncDataToLocalStorage(remotedata);
function resolveSync(remotedata, remotestateversion) {
var localstateversion = getStorage("syncstateversion");
console.log("Resolving sync: remote state: " + remotestateversion, "local state: " + localstateversion);
if (localstateversion == remotestateversion) {
// Server and client both have same version
console.log("Sync: server is same as client");
return true;
}
if (localchangetime < remotedata.changed) {
// The server has newer stuff for us
syncDataToLocalStorage(remotedata);
} else if (Number(localstateversion) < Number(remotestateversion)) {
// Server has newer version
console.log("Sync: server is newer than client");
syncDataToLocalStorage(remotedata, remotestateversion);
return true;
}
if (localchangetime >= remotedata.changed) {
// Our local data is newer or the same as the server copy
} else {
// We have the newer version
console.log("Sync: client is newer than server.");
return true;
}
return false;
@ -70,10 +65,11 @@ function syncNow(callback) {
$.post(SETTINGS.syncapi, {
username: username,
password: password,
data: JSON.stringify(data)
data: JSON.stringify(data),
stateversion: data.stateversion
}, function (resp) {
if (resp.status == "OK") {
resolveSync(resp.data);
resolveSync(resp.data, resp.stateversion);
setStorage("lastsync", Date.now() / 1000);
if (typeof callback == "function") {
callback();

@ -367,7 +367,7 @@ var SETTINGS = {
synckeyblacklist: [
"username", "password", "trackingcodehistory", "packages",
"user_latitude", "user_longitude", "geocode_cache", "scanevents",
"lastsync", "lastchange"
"lastsync", "lastchange", "syncstateversion"
],
geocodecacheexpiry: 604800, // One week
geocodeapi: "https://apis.netsyms.net/packagehelper/geocode.php",
@ -377,7 +377,7 @@ var SETTINGS = {
geoipapi: "https://data.netsyms.net/v1/net/geoip/key=packagehelper1/",
sharelistapi: "https://apis.netsyms.net/packagehelper/sharepackagelist.php",
loginurl: "https://apis.netsyms.net/packagehelper/login/",
syncapi: "https://apis.netsyms.net/packagehelper/sync.php",
syncapi: "https://apis.netsyms.net/packagehelper/sync_1.7.php",
mapfixapi: "https://apis.netsyms.net/packagehelper/contribgeocode.php",
addrlookupapi: "https://apis.netsyms.net/packagehelper/addresslookup.php"
}

Loading…
Cancel
Save