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 * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -9,7 +9,7 @@
* Save something to persistent storage. * Save something to persistent storage.
* @param {string} key * @param {string} key
* @param {string} value non-string values are converted to strings. * @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} * @returns {undefined}
*/ */
function setStorage(key, value, nochangeupdate) { function setStorage(key, value, nochangeupdate) {
@ -18,7 +18,8 @@ function setStorage(key, value, nochangeupdate) {
} }
localStorage.setItem(key, value); localStorage.setItem(key, value);
if (!nochangeupdate && !SETTINGS.synckeyblacklist.includes(key)) { 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() { function gatherSyncData() {
if (getStorage("syncstateversion") == null) {
setStorage("syncstateversion", 0);
}
var data = { var data = {
localStorage: {}, 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(); var allitems = getAllStorage();
for (var i = 0; i < allitems.length; i++) { for (var i = 0; i < allitems.length; i++) {
var key = allitems[i].key; var key = allitems[i].key;
@ -27,33 +25,30 @@ function gatherSyncData() {
return data; return data;
} }
function syncDataToLocalStorage(data) { function syncDataToLocalStorage(data, stateversion) {
for (var key in data.localStorage) { for (var key in data.localStorage) {
if (data.localStorage.hasOwnProperty(key)) { if (data.localStorage.hasOwnProperty(key)) {
setStorage(key, data.localStorage[key], true); setStorage(key, data.localStorage[key], true);
} }
} }
setStorage("syncstateversion", stateversion);
} }
function resolveSync(remotedata) { function resolveSync(remotedata, remotestateversion) {
var localchangetime = getStorage("lastchange"); var localstateversion = getStorage("syncstateversion");
if (remotedata.changed == null) { console.log("Resolving sync: remote state: " + remotestateversion, "local state: " + localstateversion);
// The server has nothing, this is the first sync if (localstateversion == remotestateversion) {
return true; // Server and client both have same version
} console.log("Sync: server is same as client");
if (localchangetime == null) {
// No local setting changes but since we've gotten this far,
// the server has stuff for us
syncDataToLocalStorage(remotedata);
return true; return true;
} } else if (Number(localstateversion) < Number(remotestateversion)) {
if (localchangetime < remotedata.changed) { // Server has newer version
// The server has newer stuff for us console.log("Sync: server is newer than client");
syncDataToLocalStorage(remotedata); syncDataToLocalStorage(remotedata, remotestateversion);
return true; return true;
} } else {
if (localchangetime >= remotedata.changed) { // We have the newer version
// Our local data is newer or the same as the server copy console.log("Sync: client is newer than server.");
return true; return true;
} }
return false; return false;
@ -70,10 +65,11 @@ function syncNow(callback) {
$.post(SETTINGS.syncapi, { $.post(SETTINGS.syncapi, {
username: username, username: username,
password: password, password: password,
data: JSON.stringify(data) data: JSON.stringify(data),
stateversion: data.stateversion
}, function (resp) { }, function (resp) {
if (resp.status == "OK") { if (resp.status == "OK") {
resolveSync(resp.data); resolveSync(resp.data, resp.stateversion);
setStorage("lastsync", Date.now() / 1000); setStorage("lastsync", Date.now() / 1000);
if (typeof callback == "function") { if (typeof callback == "function") {
callback(); callback();

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

Loading…
Cancel
Save