gecko-dev/services/sync/modules-testing/rotaryengine.js
Lina Cambridge 6245c3b363 Bug 1636365 - Split out persistence from Tracker into LegacyTracker. r=markh,rfkelly
The tracker base class currently does two things: bump the score in
response to observer notifications, and store a list of changed IDs.
The bookmarks, form autofill, and now bridged trackers need to hack
around this to opt out of persistence, since they handle change
tracking in the storage layer.

This commit keeps the score logic in `Tracker`, but moves all the
persistence code into an intermediate `LegacyTracker` class, and
changes all engines that need persistence to inherit from it.

`ignoreAll` is more interesting. We want new-style stores to emit
observer notifications with change sources, so that the tracker knows
to ignore changes made by Sync. Ignoring all observer notifications
during a sync is a blunter version of this. But, not every new store
supports change sources, so we reimplement `ignoreAll` manually for
ones that don't.

Differential Revision: https://phabricator.services.mozilla.com/D74374
2020-05-13 03:56:53 +00:00

129 lines
2.8 KiB
JavaScript

/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = [
"RotaryEngine",
"RotaryRecord",
"RotaryStore",
"RotaryTracker",
];
const { Store, SyncEngine, LegacyTracker } = ChromeUtils.import(
"resource://services-sync/engines.js"
);
const { CryptoWrapper } = ChromeUtils.import(
"resource://services-sync/record.js"
);
const { SerializableSet, Utils } = ChromeUtils.import(
"resource://services-sync/util.js"
);
/*
* A fake engine implementation.
* This is used all over the place.
*
* Complete with record, store, and tracker implementations.
*/
function RotaryRecord(collection, id) {
CryptoWrapper.call(this, collection, id);
}
RotaryRecord.prototype = {
__proto__: CryptoWrapper.prototype,
};
Utils.deferGetSet(RotaryRecord, "cleartext", ["denomination"]);
function RotaryStore(name, engine) {
Store.call(this, name, engine);
this.items = {};
}
RotaryStore.prototype = {
__proto__: Store.prototype,
async create(record) {
this.items[record.id] = record.denomination;
},
async remove(record) {
delete this.items[record.id];
},
async update(record) {
this.items[record.id] = record.denomination;
},
async itemExists(id) {
return id in this.items;
},
async createRecord(id, collection) {
let record = new RotaryRecord(collection, id);
if (!(id in this.items)) {
record.deleted = true;
return record;
}
record.denomination = this.items[id] || "Data for new record: " + id;
return record;
},
async changeItemID(oldID, newID) {
if (oldID in this.items) {
this.items[newID] = this.items[oldID];
}
delete this.items[oldID];
},
async getAllIDs() {
let ids = {};
for (let id in this.items) {
ids[id] = true;
}
return ids;
},
async wipe() {
this.items = {};
},
};
function RotaryTracker(name, engine) {
LegacyTracker.call(this, name, engine);
}
RotaryTracker.prototype = {
__proto__: LegacyTracker.prototype,
};
function RotaryEngine(service) {
SyncEngine.call(this, "Rotary", service);
// Ensure that the engine starts with a clean slate.
this.toFetch = new SerializableSet();
this.previousFailed = new SerializableSet();
}
RotaryEngine.prototype = {
__proto__: SyncEngine.prototype,
_storeObj: RotaryStore,
_trackerObj: RotaryTracker,
_recordObj: RotaryRecord,
async _findDupe(item) {
// This is a Special Value® used for testing proper reconciling on dupe
// detection.
if (item.id == "DUPE_INCOMING") {
return "DUPE_LOCAL";
}
for (let [id, value] of Object.entries(this._store.items)) {
if (item.denomination == value) {
return id;
}
}
return null;
},
};