Add bindings for implementing Sync engines in Rust
Categories
(Firefox :: Sync, defect, P1)
Tracking
()
Tracking | Status | |
---|---|---|
firefox77 | --- | fixed |
People
(Reporter: lina, Assigned: lina)
References
(Regression)
Details
(Keywords: regression)
Attachments
(1 file, 2 obsolete files)
As part of shipping Remerge (generic sync) on Desktop, we'll need to figure out how to integrate it with the existing Sync machinery. In a-s, this is handled entirely by the sync15
crate, which manages authentication with the token server, setting up the server, fetching and uploading BSOs, and record crypto.
It also provides a Store
abstraction, which all our syncable data stores implement, as well as top-level sync
functions for kicking the whole process off.
Shipping sync15
on Desktop will be tricky to do in its current state, because it pulls in networking libraries, and also (IIUC) depends on the a-s copy of NSS for crypto. Long-term, we'll definitely consider writing a Viaduct backend for HTTP requests, and linking to Gecko. Additionally, Desktop already has logic for talking to the token server, setting up storage, and downloading and uploading records. Having two state machines run as part of the same sync also duplicates work, and introduces more opportunities for things to go wrong.
In the meantime, we can make incremental progress by using our existing Sync code, and having the Rust code do all the heavy lifting for merging and storage. This would also bring us a step closer to landing Rust components on Desktop, without boiling the ocean.
Let's use this bug to brainstorm and prototype ideas.
Assignee | ||
Comment 1•5 years ago
|
||
I'll go first, to get things going! 😁
I wonder, can we use Rust XPCOM bindings to make a "native engine", with the guts of the storage and merging logic encapsulated entirely in Rust, but leaning on the Sync JS code for networking and crypto? I'm imagining a minimal interface that looks something like this:
interface mozIBridgedSyncEngineCallback {
void handleSuccess(in nsIVariant result);
void handleError(in AString message);
};
interface mozIBridgedSyncEngineSyncCallback : mozIBridgedSyncEngineCallback {
void queueForUpload(in AString collectionName,
in Array<AString> recordsAsJSON);
};
interface mozIBridgedSyncEngine {
attribute mozISyncedBookmarksMirrorLogger logger;
void getLastSync(in AString collectionName,
in mozIBridgedSyncEngineCallback callback);
void setLastSync(in AString collectionName,
in mozIBridgedSyncEngineCallback callback);
void withIncomingRecords(in AString collectionName,
in Array<AString> recordsAsJSON);
mozIPlacesPendingOperation sync(in mozIBridgedSyncEngineCallback callback);
void syncFinished(in AString collectionName,
in Array<AString> uploadedIds);
};
Since we already get a JSON string when we decrypt incoming records, we can pass them directly over to Rust, instead of parsing them and inflating them into records on the JS side. The JS side would also take care of fetching from the data and metadata collections (if we keep using multiple collections), and the Rust code would stitch it together.
A Rust implementation of mozIBridgedSyncEngine
would also manage a background thread, which we can use for merging and running synchronous storage operations. Gecko has a thread pool designed for this kind of thing, which we can lean on. We'll also need to figure out initializing the database connection, how we run storage operations, whether we use Rusqlite or mozStorage—but one step at a time. sync
returns an interruptible operation, and there's a logger that we can use to integrate with Sync logging, like we do for bookmarks now...but, other than that, merging is completely opaque to the Sync JS code.
On success, Remerge can hand us records to upload, which we'd queue on the JS side until handleSuccess
is called. We'd encrypt these directly, without parsing them first, and upload them to the data and meta collections.
There's also some boilerplate-y methods for managing the last sync time, which the JS side needs to know to fetch and upload records, and syncFinished
, to tell Remerge to write everything that just got uploaded back to its mirror.
There isn't nearly enough detail in this—and, when it comes to Sync, the 😈 is in the details—but something to get us started.
Assignee | ||
Updated•5 years ago
|
Assignee | ||
Comment 2•5 years ago
|
||
Assignee | ||
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 3•5 years ago
|
||
We aren't intending to land this; this is more of a demo to show how
we could expose and configure bridged Rust storage (and soon, sync!)
interfaces.
Depends on D65268
Assignee | ||
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 4•5 years ago
|
||
Depends on D65268
Updated•5 years ago
|
Assignee | ||
Comment 5•5 years ago
|
||
OK, I think this is finally ready for review! I think the order of dependencies here will turn out to be something like this:
- Review and land D65268. I put up the extension storage and autofill storage as examples, but neither of those should land—they're just showing how we could use Golden Gate to hook up a Rust engine.
- Once that's in, file and fix follow-up tickets for the
TODO
s in that patch: for example, exposingmodified
to Rust, refactoringCryptoWrapper
to avoid the parse-then-stringify dance that we do now, and so on. - In parallel, get bug 1623245 (and the a-s pieces) to a reviewable state, with syncing hooked up. We'll also likely make changes to Golden Gate as we work on this. Bug 1623245 depends on having the a-s engine in place and vendored, which also means vendoring Rusqlite.
How does that sound?
Assignee | ||
Comment 6•5 years ago
|
||
Assignee | ||
Comment 7•5 years ago
|
||
Comment 9•5 years ago
|
||
Backed out changeset 2b02e71f1780 (Bug 1596322) for multiple xpcshell failures
https://hg.mozilla.org/integration/autoland/rev/af83e3025c32064daa618e48cee2b051157d60f1
Failure log:
https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=296872748&repo=autoland&lineNumber=3347
https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=296872878&repo=autoland&lineNumber=2743
Comment 10•5 years ago
|
||
and there are also some bc failures: https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=296884817&repo=autoland&lineNumber=2979
Comment 11•5 years ago
|
||
Comment 12•5 years ago
|
||
bugherder |
Comment 13•5 years ago
|
||
Backed out changeset d8ef791a2165 (bug 1596322) for browser_all_files_referenced.js failures
Backout link: https://hg.mozilla.org/integration/autoland/rev/dfb06ae2f058e6743e0e7baab5d2625b62d7bd33
Failure log: https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=296920268&repo=autoland&lineNumber=3391
[task 2020-04-09T09:35:43.414Z] 09:35:43 INFO - TEST-START | browser/base/content/test/static/browser_all_files_referenced.js
[task 2020-04-09T09:35:49.277Z] 09:35:49 INFO - TEST-INFO | started process screencapture
[task 2020-04-09T09:35:49.413Z] 09:35:49 INFO - TEST-INFO | screencapture: exit 0
[task 2020-04-09T09:35:49.413Z] 09:35:49 INFO - Buffered messages logged at 09:35:43
[task 2020-04-09T09:35:49.413Z] 09:35:49 INFO - Entering test bound checkAllTheFiles
[task 2020-04-09T09:35:49.413Z] 09:35:49 INFO - Buffered messages logged at 09:35:49
[task 2020-04-09T09:35:49.413Z] 09:35:49 INFO - indirectly whitelisted file: chrome://marionette/content/test_dialog.dtd used from chrome://marionette/content/test_dialog.xhtml
...
[task 2020-04-09T09:35:49.431Z] 09:35:49 INFO - indirectly whitelisted file: chrome://fxr/content/prefs.js used from chrome://fxr/content/prefs.html
[task 2020-04-09T09:35:49.431Z] 09:35:49 INFO - Buffered messages finished
[task 2020-04-09T09:35:49.431Z] 09:35:49 INFO - TEST-UNEXPECTED-FAIL | browser/base/content/test/static/browser_all_files_referenced.js | there should be no unreferenced files - Got 1, expected 0
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - Stack trace:
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:test_is:1320
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochitests/content/browser/browser/base/content/test/static/browser_all_files_referenced.js:checkAllTheFiles:950
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:Tester_execTest/<:1062
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:Tester_execTest:1097
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:nextTest/<:925
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:SimpleTest.waitForFocus/waitForFocusInner/focusedOrLoaded/<:918
[task 2020-04-09T09:35:49.432Z] 09:35:49 INFO - Not taking screenshot here: see the one that was previously logged
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - TEST-UNEXPECTED-FAIL | browser/base/content/test/static/browser_all_files_referenced.js | unreferenced file: resource://services-sync/bridged_engine.js -
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - Stack trace:
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:test_ok:1292
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochitests/content/browser/browser/base/content/test/static/browser_all_files_referenced.js:checkAllTheFiles:954
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:Tester_execTest/<:1062
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:Tester_execTest:1097
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochikit/content/browser-test.js:nextTest/<:925
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - chrome://mochikit/content/tests/SimpleTest/SimpleTest.js:SimpleTest.waitForFocus/waitForFocusInner/focusedOrLoaded/<:918
[task 2020-04-09T09:35:49.434Z] 09:35:49 INFO - ignored unused whitelist entry: resource://app/blocklist.xml
[task 2020-04-09T09:35:49.435Z] 09:35:49 INFO - ignored unused whitelist entry: resource://gre/gmp-clearkey/0.1/manifest.json
[task 2020-04-09T09:35:49.435Z] 09:35:49 INFO - ignored unused whitelist entry: resource://gre/res/test.properties
[task 2020-04-09T09:35:49.435Z] 09:35:49 INFO - missing file: resource://gre/components/nsAsyncShutdown.js
[task 2020-04-09T09:35:49.435Z] 09:35:49 INFO - missing file: resource://gre/modules/commonjs/toolkit/loader.js
[task 2020-04-09T09:35:49.445Z] 09:35:49 INFO - missing file: resource://search-extensions/yandex/__MSG_extensionIcon__
...
[task 2020-04-09T09:35:49.639Z] 09:35:49 INFO - missing file: resource://app/localization/en-US/toolkit/about/aboutCompat.ftl referenced from jar:file:///Users/cltbld/tasks/task_1586422769/build/application/Firefox%20Nightly.app/Contents/Resources/browser/features/webcompat@mozilla.org.xpi!/about-compat/aboutCompat.html
[task 2020-04-09T09:35:49.677Z] 09:35:49 INFO - Leaving test bound checkAllTheFiles
[task 2020-04-09T09:35:49.680Z] 09:35:49 INFO - Console message: No chrome package registered for chrome://geckoview/content/geckoview.xhtml
[task 2020-04-09T09:35:49.680Z] 09:35:49 INFO - Console message: No chrome package registered for chrome://gfxsanity/content/sanityparent.html
[task 2020-04-09T09:35:49.680Z] 09:35:49 INFO - Console message: No chrome package registered for chrome://help/content/help.js
[task 2020-04-09T09:35:49.750Z] 09:35:49 INFO - GECKO(2190) | MEMORY STAT vsizeMaxContiguous not supported in this build configuration.
[task 2020-04-09T09:35:49.750Z] 09:35:49 INFO - GECKO(2190) | MEMORY STAT | vsize 8092MB | residentFast 808MB | heapAllocated 541MB
[task 2020-04-09T09:35:49.750Z] 09:35:49 INFO - TEST-OK | browser/base/content/test/static/browser_all_files_referenced.js | took 6278ms
Comment 14•5 years ago
|
||
Please also note that I did a local build which had the last landing of this patch (rev d8ef791a2165) but not the latest backout. On a clobber build, the Cargo.lock
file at the root of the tree gets modified to remove the golden_gate
and golden_gate_traits
crates. I'm guessing this is because the Cargo.toml
file wasn't updated to reference these crates and something in the build does a cargo update
or similar causing the lockfile to throw out these changes. Please take a look before re-landing, thanks!
Assignee | ||
Comment 15•5 years ago
|
||
Oh, thanks for the heads-up, Kats! The Cargo.lock
changes are, indeed, because the two [DO NOT LAND]
example commits use golden_gate
, but not the first one. I updated that, and also fixed the browser_all_files_referenced.js
failure.
Assignee | ||
Updated•5 years ago
|
Comment 16•5 years ago
|
||
Comment 17•5 years ago
|
||
bugherder |
Updated•5 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Updated•3 years ago
|
Updated•2 years ago
|
Description
•