CloudServices/Sync/FxSync/Developer/ClientAPI: Difference between revisions
Line 7: | Line 7: | ||
== Writing a Tracker class == | == Writing a Tracker class == | ||
Your tracker class must inherit from <tt>Tracker</tt>, which is defined in <tt>weave/engines/trackers.js</tt>. | Your tracker class must inherit from <tt>Tracker</tt>, which is defined in <tt>weave/engines/trackers.js</tt>. Its purpose in life is to track changes to whatever data type you are syncing. It must maintain a list of GUIDs for objects that have been changed and therefore require syncing. It also has to maintain a "score", which is a number from 0 to 100 which represents "how badly does this data type need to be synced right now". | ||
Getting your tracker to track changes in the underlying data is probably easiest to do if you register your tracker as an observer, so that it can receive notifications from one or more Mozilla components. What events you listen for is entirely up to you. You can find out more about registering as an observer here: [link]. | |||
=== The Score === | === The Score === |
Revision as of 02:03, 30 January 2009
Overview
Writing a Record class
Writing a Store class
Writing a Tracker class
Your tracker class must inherit from Tracker, which is defined in weave/engines/trackers.js. Its purpose in life is to track changes to whatever data type you are syncing. It must maintain a list of GUIDs for objects that have been changed and therefore require syncing. It also has to maintain a "score", which is a number from 0 to 100 which represents "how badly does this data type need to be synced right now".
Getting your tracker to track changes in the underlying data is probably easiest to do if you register your tracker as an observer, so that it can receive notifications from one or more Mozilla components. What events you listen for is entirely up to you. You can find out more about registering as an observer here: [link].
The Score
The score is stored in this._score, a variable defined by the base Tracker class. Set your score by assigning a value to this._score.
The score number is used by the scheduler to decide when your engine will be synced. Setting it to zero means "I have no need to sync". The higher you set this number, the more urgently the scheduler treats your request. Setting it to 100 means "Sync me immediately". It's up to you to figure out the best way to assign a score based on the current state of whatever data type you're tracking.
Your tracker score is automatically reset to zero after each time your engine syncs.
The changed GUID list
The base class maintains a list of GUIDs that need syncing. When your tracker detects that an item has changed, you should add it to this list by calling:
this.addChangedID(guid);
These GUIDs correspond to the .id fields of your Record objects; see the section on the Store class for more about defining and maintaining the mapping between GUIDs and Records.
Example
Here's the skeleton of a sample Tracker class.
function FooTracker() { this._init(); } FooTracker.prototype = { __proto__: Tracker.prototype, _logName: "FooTracker", file: "foo", _init: function FooTracker_init() { // The ugly syntax on the next line calls the base class's init method: this.__proto__.__proto__.init.call(this); /* Here is where you would register your tracker as an observer, so that its onEvent() (or other appropriately named) method can be called in response to events. */ }, onEvent: function FooTracker_onEvent() { /* Here is where you'd handle the event. See the documentation for whatever service you are observing to find out what to call this method, what arguments to expect, and how to interpret them. */ var guid = 0; /* Here is where you'd include code to figure out the GUID of the item that has changed... */ this.addChangedId(guid); // Update the score as you see fit: this._score += 10; } };
Writing an Engine class
Your Engine class serves to tie together your Store, Tracker, and Record classes into a bundle that the Weave sync algorithm can instantiate and use.
You're probably sick of writing subclasses by this point, but don't worry: this one is very easy. I saved it for last because it requires the least code.
Your class must derive from the SyncEngine class, defined in weave/modules/engines.js. SyncEngine contains a lot of code which handles logic for the core sync algorithm, but your subclass won't need to call any of this directly, unless you are overriding part of the sync algorithm to provide custom sync behavior (an advanced technique outside the scope of this article).
A sample Engine class:
function FooEngine() { this._init(); } FooEngine.prototype = { __proto__: SyncEngine.prototype, name: "foo", displayName: "Foo", logName: "Foo", _storeObj: FooStore, _trackerObj: FooTracker };
As you can see, there isn't actually any new code here at all; the prototype simply defines some metadata such as the Store and Tracker classes to use, and the human-readable name that will be used in the log files to identify errors and status messages coming from this engine.
(Don't forget that you'll need to import SyncEngine and export FooEngine. So the top of your file should include:)
const EXPORTED_SYMBOLS = ["FooEngine", /* ... etc... */ ]; const Cu = Components.utils; // etc... Cu.import("resource://weave/engines.js");