canmove, Confirmed users
640
edits
(→API) |
No edit summary |
||
Line 3: | Line 3: | ||
== Proposal == | == Proposal == | ||
Reduce to two classes: ''Repository'' and ''Synchronizer'': | Reduce to two main classes: ''Repository'' and ''Synchronizer'': | ||
* ''Repositories'' are both sinks and sources of records | * ''Repositories'' are both sinks and sources of records | ||
* ''Synchronizers'' exist (from one perspective, at least) to reify the relationship between two Repositories (including tracking <tt>lastSync</tt>), which in practice means connecting a pair of repositories as source then sink in turn. | * ''Synchronizers'' exist (from one perspective, at least) to reify the relationship between two Repositories (including tracking <tt>lastSync</tt>), which in practice means connecting a pair of repositories as source then sink in turn. | ||
These actions actually take place via ''RepositorySession''s and ''SynchronizerSession''s, which represent single sync events. | |||
Repository(Session)s are entirely responsible for providing a timestamp- and record-centric API over a source of data. This interface abstracts the tracking of changed items and application and retrieval of records, and is uniform across both remote and local storage. For example, we would build a ''FxBookmarkRepository'' layer above Places, a ''ServerRepository'' layer in front of the v5/v1.1 Sync API, and connect the two with a simple Synchronizer. Both Repository implementations would implement ''exactly the same interface'', which would allow us to trivially implement: | |||
* Direct sync between two devices, without a server intermediary | * Direct sync between two devices, without a server intermediary | ||
Line 23: | Line 25: | ||
== API == | == API == | ||
The API for Repository is defined in terms of callbacks, each of which can be called multiple times (e.g., as batches of records arrive) | The API for Repository/RepositorySession is defined in terms of callbacks, each of which can be called multiple times (e.g., as batches of records arrive). A callback invocation takes an error argument, and optionally one or more records, as input. Each invocation can be provided with a <tt>DONE</tt> constant to indicate completion. Callbacks can invoke an <tt>abort</tt> method on the session to (optionally) prevent further cycles. | ||
Classes are (links will rot): | |||
* [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L54 Repository] | |||
** [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L223 Server11Repository] | |||
** [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L552 Crypto5Middleware] | |||
''createSession'' returns (via a callback) a ''RepositorySession'': | |||
* | * [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L93 RepositorySession] | ||
** | ** [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L264 Server11Session] | ||
** [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L638 Crypto5StoreSession] | |||
** [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/repository.js#L733 TrackingSession] | |||
Synchronizer holds two Repositories, creating sessions appropriately. | |||
Synchronizer classes are: | |||
* | * [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/synchronizer.js#L46 SynchronizerSession] | ||
* | * [https://github.com/rnewman/alder/blob/repositories/services/sync/modules/synchronizer.js#L271 Synchronizer] | ||
== Questions and considerations == | |||
* Q: Where does batching happen? A: Within each RepositorySession implementation. | |||
? | |||
* As much storage as possible should be pushed down into the data store. That should allow these classes to be effectively stateless; the two query inputs are modified time and GUID. Tracking should be reduced to deleted items, and even that can be elided. | * As much storage as possible should be pushed down into the data store. That should allow these classes to be effectively stateless; the two query inputs are modified time and GUID. Tracking should be reduced to deleted items, and even that can be elided. | ||
* I'm very intrigued by deltas. It should be possible to stage rollout through an appropriate wrapper store. | * I'm very intrigued by deltas. It should be possible to stage rollout through an appropriate wrapper store. |