diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /services/sync/docs | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | services/sync/docs/engines.rst | 133 | ||||
-rw-r--r-- | services/sync/docs/external.rst | 8 | ||||
-rw-r--r-- | services/sync/docs/index.rst | 16 | ||||
-rw-r--r-- | services/sync/docs/overview.rst | 81 | ||||
-rw-r--r-- | services/sync/docs/rust-engines.rst | 37 |
5 files changed, 275 insertions, 0 deletions
diff --git a/services/sync/docs/engines.rst b/services/sync/docs/engines.rst new file mode 100644 index 0000000000..7a4fa721af --- /dev/null +++ b/services/sync/docs/engines.rst @@ -0,0 +1,133 @@ +============================ +The Sync engines in the tree +============================ + +Unless otherwise specified, the engine implementations can be found +`here <https://searchfox.org/mozilla-central/source/services/sync/modules/engines>`_ + +Please read the :doc:`overview`. + +Clients +======= + +The ``clients`` engine is a special engine in that it's invisible to the +user and can not be disabled - think of it as a "meta" engine. As such, it +doesn't really have a sensible concept of ``store`` or ``tracker``. + +The engine is mainly responsible for keeping its own record current in the +``clients`` collection. Some parts of Sync use this collection to know what +other clients exist and when they last synced (although alot of this is moving +to using the Firefox Accounts devices). + +Clients also has the ability to handle ``commands`` - in short, some other +client can write to this client's ``commands``, and when this client notices, +it will execute the command. Commands aren't arbitrary, so commands must be +understood by both sides for them to work. There are commands to "wipe" +collections etc. In practice, this is used only by ``bookmarks`` when a device +restores bookmarks - in that case, the restoring device will send a ``wipe`` +command to all other clients so that they take the new bookmarks instead of +merging them. + +If not for this somewhat limited ``commands`` functionality, this engine could +be considered deprecated and subsumed by FxA devices - but because we +can't just remove support for commands and also do not have a plan for +replacing them, the clients engine remains important. + +Bookmarks +========= + +The ``bookmarks`` engine has changed so that it's tightly integrated with the +``places`` database. Instead of an external ``tracker``, the tracking is +integrated into Places. Each bookmark has a `syncStatus` and a +`syncChangeCounter` and these are managed internally by places. Sync then just +queries for changed bookmarks by looking for these fields. + +Bookmarks is somewhat unique in that it needs to maintain a tree structure, +which makes merging a challenge. The `dogear <https://github.com/mozilla/dogear>`_ +component (written in Rust and also used by the +`application-services bookmarks component <https://github.com/mozilla/application-services/tree/main/components/places>`_) +performs this merging. + +Bookmarks also pioneered the concept of a "mirror" - this is a database table +which tracks exactly what is on the server. Because each sync only fetches +changes from the server since the last sync, each sync does not supply every +record on the server. However, the merging code does need to know what's on +the server - so the mirror tracks this. + +History +======= + +History is similar to bookmarks described above - it's closely integrated with +places - but is less complex because there's no tree structure involved. + +One unique characteristic of history is that the engine takes steps to *not* +upload everything - old profiles tend to have too much history to reasonably +store and upload, so typically uploads are limited to the last 5000 visits. + +Logins +====== + +Logins has also been upgraded to be closely integrated with `Services.logins` - +the logins component itself manages the metadata. + +Tabs +==== + +Tabs is a special engine in that there's no underlying storage at all - it +both saves the currently open tabs from this device (which are enumerated +every time it's updated) and also lets other parts of Firefox know which tabs +are open on other devices. There's no database - if we haven't synced yet we +don't know what other tabs are open, and when we do know, the list is just +stored in memory. + +The `SyncedTabs module <https://searchfox.org/mozilla-central/source/services/sync/modules/SyncedTabs.jsm>`_ +is the main interface the browser uses to get the list of tabs from other +devices. + +Add-ons +======= + +Addons is still an "old school" engine, with a tracker and store which aren't +closely integrated with the addon manager. As a result it's fairly complex and +error prone - eg, it persists the "last known" state so it can know what to +sync, where a better model would be for the addon manager to track the changes +on Sync's behalf. + +It also attempts to sync themes etc. The future of this engine isn't clear given +it doesn't work on mobile platforms. + +Addresses / Credit-Cards +======================== + +Addresses and Credit-cards have Sync functionality tightly bound with the +store. Unlike other engines above, this engine has always been tightly bound, +because it was written after we realized this tight-binding was a feature and +not a bug. + +Technically these are 2 separate engines and collections. However, because the +underlying storage uses a shared implementation, the syncing also uses a +shared implementation - ie, the same logic is used for both - so we tend to +treat them as a single engine in practice. + +As a result, only a shim is in the `services/sync/modules/engines/` directory, +while the actual logic is +`next to the storage implementation <https://searchfox.org/mozilla-central/source/toolkit/components/formautofill/FormAutofillSync.jsm>`_. + +This engine has a unique twist on the "mirror" concept described above - +whenever a change is made to a fields, the original value of the field is +stored directly in the storage. This means that on the next sync, the value +of the record on the server can be deduced, meaning a "3-way" merge can be +done, so it can better tell the difference between local only, remote only, or +conflicting changes. + +WebExt-Storage +============== + +webext-storage is implemented in Rust and lives in +`application services <https://github.com/mozilla/application-services/tree/main/components/webext-storage>`_ +and is vendored into the `addons code <https://searchfox.org/mozilla-central/source/toolkit/components/extensions/storage/webext_storage_bridge>`_ - +note that this includes the storage *and* Sync code. The Sync engine itself +is a shim in the sync directory. + +See the :doc:`rust-engines` document for more about how rust engines are +integrated. diff --git a/services/sync/docs/external.rst b/services/sync/docs/external.rst new file mode 100644 index 0000000000..f7cebde32d --- /dev/null +++ b/services/sync/docs/external.rst @@ -0,0 +1,8 @@ +============== +External Links +============== + +Some external links that might be of interest: + +* `Information about the server APIs <https://mozilla-services.readthedocs.io/en/latest/index.html>`_ +* `Some external Sync Client docs <https://mozilla-services.readthedocs.io/en/latest/sync/index.html>`_ diff --git a/services/sync/docs/index.rst b/services/sync/docs/index.rst new file mode 100644 index 0000000000..a484332f3d --- /dev/null +++ b/services/sync/docs/index.rst @@ -0,0 +1,16 @@ +==== +Sync +==== + +This documents the sync implementation inside mozilla-central. It assumes +a general understanding of what Sync is and how it works at a high level - you +can find `some external docs <https://mozilla-services.readthedocs.io/en/latest/sync/>`_ +which can help with this. + +.. toctree:: + :maxdepth: 1 + + overview + engines + rust-engines + external diff --git a/services/sync/docs/overview.rst b/services/sync/docs/overview.rst new file mode 100644 index 0000000000..e956090d70 --- /dev/null +++ b/services/sync/docs/overview.rst @@ -0,0 +1,81 @@ +==================== +Introduction to Sync +==================== + +This document is a brief introduction to how Sync is implemented in desktop Firefox. + +General, Historical, Anatomy of a Sync Engine +============================================= + +This section describes how Sync used to work - and indeed, how much of it still +does. While we discuss how this is slowly changing, this context is valuable. + +For any datatype which syncs, there tends to be 3 parts: + +Store +----- + +The sync ``store`` interfaces with the actual Firefox desktop store. For example, +in the ``passwords`` engine, the "store" is that layer that talks to +``Services.logins`` + +Tracker +------- + +The ``tracker`` is what knows that something should be synced. For example, +when the user creates or updates a password, it is the tracker that knows +we should sync now, and what particular password(s) should be updated. + +This is typically done via "observer" notifications - ``Services.logins``, +``places`` etc all send specific notifications when certain events happen +(and indeed, some of these were added for Sync's benefit) + +Engine +------ + +The ``engine`` ties it all together. It works with the ``store`` and +``tracker`` and tracks its own metadata (eg, the timestamp of the passwords on +the server, so it knows how to grab just changed records and how to pass them +off to the ``store`` so the actual underlying storage can be updated. + +All of the above parts were typically in the +`services/sync/modules/engines directory <https://searchfox.org/mozilla-central/source/services/sync/modules/engines>`_ +directory and decoupled from the data they were syncing. + + +The Future of Desktop-Specific Sync Engines +=========================================== + +The system described above reflects the fact that Sync was "bolted on" to +Desktop Firefox relatively late - eg, the Sync ``store`` is decoupled from the +actual ``store``. This has causes a number of problems - particularly around +the ``tracker`` and the metadata used by the engine, and the fact that changes +to the backing store would often forget that Sync existed. + +Over the last few years, the Sync team has come to the conclusion that Sync +support must be integrated much closer to the store itself. For example, +``Services.logins`` should track when something has changed that would cause +an item to be synced. It should also track the metadata for the store so that +if (say) a corrupt database is recovered by creating a new, empty one, the +metadata should also vanish so Sync knows something bad has happened and can +recover. + +However, this is a slow process - currently the ``bookmarks``, ``history`` and +``passwords`` legacy engines have been improved so more responsibility is taken +by the stores. In all cases, for implementation reasons, the Sync +implementation still has a ``store``, but it tends to be a thin wrapper around +the actual underlying store. + +The Future of Cross-Platform Sync Engines +========================================= + +There are a number of Sync engines implemented in Rust and which live in the +application-services repository. While these were often done for mobile +platforms, the longer term hope is that they can be reused on Desktop. +:doc:`engines` has more details on these. + +While no existing engines have been replaced with Rust implemented engines, +the webext-storage engine is implemented in Rust via application-services, so +doesn't tend to use any of the infrastructure described above. + +Hopefully over time we will find more Rust-implemented engines in Desktop. diff --git a/services/sync/docs/rust-engines.rst b/services/sync/docs/rust-engines.rst new file mode 100644 index 0000000000..af00fd6619 --- /dev/null +++ b/services/sync/docs/rust-engines.rst @@ -0,0 +1,37 @@ +================================ +How Rust Engines are implemented +================================ + +There are 2 main components to engines implemented in Rust + +The bridged-engine +================== + +Because Rust engines still need to work with the existing Sync infrastructure, +there's the concept of a `bridged-engine <https://searchfox.org/mozilla-central/source/services/sync/modules/bridged_engine.js>`_. +In short, this is just a shim between the existing +`Sync Service <https://searchfox.org/mozilla-central/source/services/sync/modules/service.js>`_ +and the Rust code. + +The bridge +========== + +`"Golden Gate" <https://searchfox.org/mozilla-central/source/services/sync/golden_gate>`_ +is a utility to help bridge any Rust implemented Sync engines with desktop. In +other words, it's a "rusty bridge" - get it? Get it? Yet another of Lina's puns +that live on! + +One of the key challenges with integrating a Rust Sync component with desktop +is the different threading models. The Rust code tends to be synchronous - +most functions block the calling thread to do the disk or network IO necessary +to work - it assumes that the consumer will delegate this to some other thread. + +So golden_gate is this background thread delegation for a Rust Sync engine - +gecko calls golden-gate on the main thread, it marshalls the call to a worker +thread, and the result is marshalled back to the main thread. + +It's worth noting that golden_gate is just for the Sync engine part - other +parts of the component (ie, the part that provides the functionality that's not +sync related) will have its own mechanism for this. For example, the +`webext-storage bridge <https://searchfox.org/mozilla-central/source/toolkit/components/extensions/storage/webext_storage_bridge/src>`_ +uses a similar technique `which has some in-depth documentation <../../toolkit/components/extensions/webextensions/webext-storage.html>`_. |