2020-04-09 18:45:37 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2020-06-27 22:15:17 +03:00
|
|
|
#include "mozIServicesLogSink.idl"
|
2020-04-09 18:45:37 +03:00
|
|
|
#include "nsISupports.idl"
|
|
|
|
|
|
|
|
interface nsIVariant;
|
|
|
|
|
|
|
|
// A generic callback called with a result. Variants are automatically unboxed
|
|
|
|
// in JavaScript: for example, a `UTF8String` will be passed as a string
|
|
|
|
// argument; an `Int32` or `Int64` as a number. Methods that don't return a
|
|
|
|
// value, like `setLastSync` or `setUploaded`, will pass a `null` variant to
|
|
|
|
// `handleSuccess`. For all callback types in this file, either `handleSuccess`
|
|
|
|
// or `handleError` is guaranteed to be called once.
|
|
|
|
[scriptable, uuid(9b7dd2a3-df99-4469-9ea9-61b222098695)]
|
|
|
|
interface mozIBridgedSyncEngineCallback : nsISupports {
|
|
|
|
void handleSuccess(in nsIVariant result);
|
|
|
|
void handleError(in nsresult code, in AUTF8String message);
|
|
|
|
};
|
|
|
|
|
|
|
|
// A callback called after the engine applies incoming records. This is separate
|
|
|
|
// from `mozIBridgedSyncEngineCallback` because variants can't hold an
|
|
|
|
// `Array<T>` type.
|
|
|
|
[scriptable, uuid(2776cdd5-799a-4009-b2f3-356d940a5244)]
|
|
|
|
interface mozIBridgedSyncEngineApplyCallback : nsISupports {
|
|
|
|
// Notifies Sync that the bridged engine has finished applying incoming
|
|
|
|
// records, and has outgoing records. Sync encrypts and uploads these
|
|
|
|
// records, and notifies the engine that the upload succeeded by
|
|
|
|
// calling `engine.setUploaded(uploadedOutgoingRecordIds, ...)`.
|
2020-05-05 01:25:00 +03:00
|
|
|
void handleSuccess(in Array<AUTF8String> outgoingEnvelopesAsJSON);
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Notifies Sync that the bridged engine failed to apply the staged records.
|
|
|
|
void handleError(in nsresult code, in AUTF8String message);
|
|
|
|
};
|
|
|
|
|
2020-05-13 06:56:55 +03:00
|
|
|
// A bridged engine is implemented in Rust. It handles storage internally, and
|
|
|
|
// exposes a minimal interface for the JS Sync code to control it.
|
2020-04-09 18:45:37 +03:00
|
|
|
[scriptable, uuid(3b2b80be-c30e-4498-8065-01809cfe8d47)]
|
|
|
|
interface mozIBridgedSyncEngine : nsISupports {
|
|
|
|
// The storage version for this engine's collection. If the version in the
|
|
|
|
// server's `meta/global` record is newer than ours, we'll refuse to sync,
|
|
|
|
// since we might not understand the data; if it's older, we'll wipe the
|
|
|
|
// collection on the server, and upload our data as if on a first sync.
|
|
|
|
readonly attribute long storageVersion;
|
|
|
|
|
2020-05-27 05:12:53 +03:00
|
|
|
// Whether this engine tolerates skipped records, where a "skipped" record
|
|
|
|
// is one that would cause the server's published limits to be exceeded
|
|
|
|
// (for example, a single record where the payload is larger than the
|
|
|
|
// server accepts.)
|
|
|
|
// If this returns true, we will just skip the record without even attempting
|
|
|
|
// to upload. If this is false, we'll abort the entire batch.
|
|
|
|
// If the engine allows this, it will need to detect this scenario by noticing
|
|
|
|
// the ID is not in the 'success' records reported to `setUploaded`.
|
|
|
|
// (Note that this is not to be confused with the fact server's can currently
|
|
|
|
// reject records as part of a POST - but we hope to remove this ability from
|
|
|
|
// the server API. Note also that this is not bullet-proof - if the count of
|
|
|
|
// records is high, it's possible that we will have committed a previous
|
|
|
|
// batch before we hit the relevant limits, so things might have been written.
|
|
|
|
// We hope to fix this by ensuring batch limits are such that this is
|
|
|
|
// impossible)
|
|
|
|
readonly attribute boolean allowSkippedRecord;
|
|
|
|
|
2020-04-09 18:45:37 +03:00
|
|
|
// Wires up the Sync logging machinery to the bridged engine. This can be
|
|
|
|
// `null`, in which case any logs from the engine will be discarded.
|
2020-06-27 22:15:17 +03:00
|
|
|
attribute mozIServicesLogSink logger;
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Returns the last sync time, in milliseconds, for this engine's
|
|
|
|
// collection. This is used to build the collection URL for fetching
|
|
|
|
// incoming records, and as the initial value of the `X-I-U-S` header on
|
|
|
|
// upload. If the engine persists incoming records in a permanent (non-temp)
|
|
|
|
// table, `getLastSync` can return a "high water mark" that's the newer of
|
|
|
|
// the collection's last sync time, and the most recent record modification
|
|
|
|
// time. This avoids redownloading incoming records that were previously
|
|
|
|
// downloaded, but not applied.
|
|
|
|
void getLastSync(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
|
|
|
// Sets the last sync time, in milliseconds. This is used to fast-forward
|
|
|
|
// the last sync time for the engine's collection after fetching all
|
|
|
|
// records, and after each `setUploaded` call with the `X-L-M` header from
|
|
|
|
// the server. It may be called multiple times per sync.
|
|
|
|
void setLastSync(in long long lastSyncMillis,
|
|
|
|
in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
|
|
|
// Returns the sync ID for this engine's collection. Used for testing;
|
|
|
|
// Sync only calls `ensureCurrentSyncId` and `resetSyncId`. On success,
|
|
|
|
// calls `callback.handleSuccess(in AUTF8String currentSyncId)`.
|
|
|
|
void getSyncId(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
|
|
|
// Generates a new sync ID for this engine, and resets all local Sync
|
|
|
|
// metadata, including the last sync time and any change flags, to start
|
|
|
|
// over as a first sync. On success, calls
|
|
|
|
// `callback.handleSuccess(newSyncId)`, where `newSyncId` is
|
|
|
|
// `AUTF8String` variant. Sync will upload the new sync ID in the
|
|
|
|
// `meta/global` record.
|
|
|
|
void resetSyncId(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
|
|
|
// Ensures that the local sync ID for the engine matches the sync ID for
|
|
|
|
// the collection on the server. On a mismatch, the engine can:
|
|
|
|
// 1. Reset all local Sync state, adopt `newSyncId` as the new sync ID,
|
|
|
|
// and call `callback.handleSuccess(newSyncId)`. Most engines should
|
|
|
|
// do this.
|
|
|
|
// 2. Ignore the given `newSyncId`, use its existing local sync ID
|
|
|
|
// without resetting any state, and call
|
|
|
|
// `callback.handleSuccess(existingSyncId)`. This is useful if, for
|
|
|
|
// example, the underlying database has been restored from a backup,
|
|
|
|
// and the engine would like to force a reset and first sync on all
|
|
|
|
// other devices.
|
|
|
|
// 3. Ignore the given `newSyncId`, reset all local Sync state, and
|
|
|
|
// generate a fresh sync ID, as if `resetSyncId`. This resets the
|
|
|
|
// engine's state everywhere, locally and on all other devices.
|
|
|
|
// If the callback is called with a different sync ID than `newSyncId`,
|
|
|
|
// Sync will reupload `meta/global` with the different ID. Otherwise, it
|
|
|
|
// will assume that the engine has adopted the `newSyncId`, and do nothing.
|
|
|
|
void ensureCurrentSyncId(in AUTF8String newSyncId,
|
|
|
|
in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
2020-05-05 09:59:32 +03:00
|
|
|
// Notifies the engine that sync is starting. The engine can use this method
|
|
|
|
// to set up temp tables for merging, for example. This will only be called
|
|
|
|
// once per sync, and before any `storeIncoming` calls.
|
|
|
|
void syncStarted(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
2020-04-09 18:45:37 +03:00
|
|
|
// Stages a batch of incoming records, and calls the `callback` when
|
|
|
|
// done. This method may be called multiple times per sync, once per
|
2020-05-05 09:59:32 +03:00
|
|
|
// incoming batch, and always after `syncStarted`. Flushing incoming records
|
|
|
|
// more often incurs more writes to disk, but avoids redownloading and
|
|
|
|
// reapplying more records if syncing is interrupted. Typically, engines
|
|
|
|
// will stage incoming records in an SQLite temp table, and merge them with
|
|
|
|
// the local database when `apply` is called.
|
2020-05-05 01:25:00 +03:00
|
|
|
void storeIncoming(in Array<AUTF8String> incomingEnvelopesAsJSON,
|
Bug 1634626 - Refactor interruption in Golden Gate. r=markh,tcsc
This commit removes the `nsICancelable` return values from all
`mozIBridgedSyncEngine` methods, and replaces them with a
`mozIInterruptible` interface that can be implemented by store
classes that support interrupting.
The `nsICancelable` pattern was intended to make each operation
interruptible, without affecting the others. But we can't guarantee
that with SQLite, because it only has a way to interrupt all
running statements on a connection, not specific ones. Further,
this pattern doesn't match what we currently do in a-s, where we
create an internal "interrupt scope" for each operation, and hand
out an "interrupt handle" for interrupting all in-progress
operations.
Storage classes like `StorageSyncArea` can opt in to interruption
by implementing `mozIInterruptible`. It's a separate interface to
protect against accidental misuse: because it interrupts all
statements on the connection, it might lose writes if the current
operation is a `set`, for example. But it's useful for testing and
debugging, so we still expose it.
This commit also changes Golden Gate ferries to hold weak references to
the `BridgedEngine`, so that they don't block teardown.
Differential Revision: https://phabricator.services.mozilla.com/D73413
2020-05-05 00:32:29 +03:00
|
|
|
in mozIBridgedSyncEngineCallback callback);
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Applies all the staged records, and calls the `callback` with
|
|
|
|
// outgoing records to upload. This will always be called after
|
|
|
|
// `storeIncoming`, and only once per sync. Application should be atomic:
|
|
|
|
// either all incoming records apply successfully, or none.
|
Bug 1634626 - Refactor interruption in Golden Gate. r=markh,tcsc
This commit removes the `nsICancelable` return values from all
`mozIBridgedSyncEngine` methods, and replaces them with a
`mozIInterruptible` interface that can be implemented by store
classes that support interrupting.
The `nsICancelable` pattern was intended to make each operation
interruptible, without affecting the others. But we can't guarantee
that with SQLite, because it only has a way to interrupt all
running statements on a connection, not specific ones. Further,
this pattern doesn't match what we currently do in a-s, where we
create an internal "interrupt scope" for each operation, and hand
out an "interrupt handle" for interrupting all in-progress
operations.
Storage classes like `StorageSyncArea` can opt in to interruption
by implementing `mozIInterruptible`. It's a separate interface to
protect against accidental misuse: because it interrupts all
statements on the connection, it might lose writes if the current
operation is a `set`, for example. But it's useful for testing and
debugging, so we still expose it.
This commit also changes Golden Gate ferries to hold weak references to
the `BridgedEngine`, so that they don't block teardown.
Differential Revision: https://phabricator.services.mozilla.com/D73413
2020-05-05 00:32:29 +03:00
|
|
|
void apply(in mozIBridgedSyncEngineApplyCallback callback);
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Notifies the engine that Sync successfully uploaded the records with the
|
|
|
|
// given IDs. This method may be called multiple times per sync, once per
|
|
|
|
// batch upload. This will always be called after `apply`.
|
Bug 1634626 - Refactor interruption in Golden Gate. r=markh,tcsc
This commit removes the `nsICancelable` return values from all
`mozIBridgedSyncEngine` methods, and replaces them with a
`mozIInterruptible` interface that can be implemented by store
classes that support interrupting.
The `nsICancelable` pattern was intended to make each operation
interruptible, without affecting the others. But we can't guarantee
that with SQLite, because it only has a way to interrupt all
running statements on a connection, not specific ones. Further,
this pattern doesn't match what we currently do in a-s, where we
create an internal "interrupt scope" for each operation, and hand
out an "interrupt handle" for interrupting all in-progress
operations.
Storage classes like `StorageSyncArea` can opt in to interruption
by implementing `mozIInterruptible`. It's a separate interface to
protect against accidental misuse: because it interrupts all
statements on the connection, it might lose writes if the current
operation is a `set`, for example. But it's useful for testing and
debugging, so we still expose it.
This commit also changes Golden Gate ferries to hold weak references to
the `BridgedEngine`, so that they don't block teardown.
Differential Revision: https://phabricator.services.mozilla.com/D73413
2020-05-05 00:32:29 +03:00
|
|
|
void setUploaded(in long long newTimestampMillis,
|
|
|
|
in Array<AUTF8String> uploadedIds,
|
|
|
|
in mozIBridgedSyncEngineCallback callback);
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Notifies the engine that syncing has finished, and the engine shouldn't
|
|
|
|
// expect any more `setUploaded` calls. At this point, any outgoing records
|
|
|
|
// that weren't passed to `setUploaded` should be assumed failed. This is
|
|
|
|
// guaranteed to be called even if the sync fails. This will only be called
|
|
|
|
// once per sync.
|
Bug 1634626 - Refactor interruption in Golden Gate. r=markh,tcsc
This commit removes the `nsICancelable` return values from all
`mozIBridgedSyncEngine` methods, and replaces them with a
`mozIInterruptible` interface that can be implemented by store
classes that support interrupting.
The `nsICancelable` pattern was intended to make each operation
interruptible, without affecting the others. But we can't guarantee
that with SQLite, because it only has a way to interrupt all
running statements on a connection, not specific ones. Further,
this pattern doesn't match what we currently do in a-s, where we
create an internal "interrupt scope" for each operation, and hand
out an "interrupt handle" for interrupting all in-progress
operations.
Storage classes like `StorageSyncArea` can opt in to interruption
by implementing `mozIInterruptible`. It's a separate interface to
protect against accidental misuse: because it interrupts all
statements on the connection, it might lose writes if the current
operation is a `set`, for example. But it's useful for testing and
debugging, so we still expose it.
This commit also changes Golden Gate ferries to hold weak references to
the `BridgedEngine`, so that they don't block teardown.
Differential Revision: https://phabricator.services.mozilla.com/D73413
2020-05-05 00:32:29 +03:00
|
|
|
void syncFinished(in mozIBridgedSyncEngineCallback callback);
|
2020-04-09 18:45:37 +03:00
|
|
|
|
|
|
|
// Resets all local Sync metadata, including the sync ID, last sync time,
|
|
|
|
// and any change flags, but preserves all data. After a reset, the engine will
|
|
|
|
// sync as if for the first time.
|
|
|
|
void reset(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
|
|
|
|
// Erases all locally stored data and metadata for this engine.
|
|
|
|
void wipe(in mozIBridgedSyncEngineCallback callback);
|
|
|
|
};
|