connect method
Future<void>
connect({
- required PowerSyncBackendConnector connector,
- SyncOptions? options,
- @Deprecated('Use SyncOptions.crudThrottleTime instead') Duration? crudThrottleTime,
- Map<
String, dynamic> ? params,
inherited
Connect to the PowerSync service, and keep the databases in sync.
The connection is automatically re-opened if it fails for any reason.
To set sync parameters used in your sync rules (if any), use SyncOptions.params. SyncOptions can also be used to tune the behavior of the sync client, see that class for more information.
Status changes are reported on statusStream
.
Implementation
Future<void> connect({
required PowerSyncBackendConnector connector,
SyncOptions? options,
@Deprecated('Use SyncOptions.crudThrottleTime instead')
Duration? crudThrottleTime,
Map<String, dynamic>? params,
}) async {
// The initialization process acquires a sync connect lock (through
// updateSchema), so ensure the database is ready before we try to acquire
// the lock for the connection.
await initialize();
final resolvedOptions = ResolvedSyncOptions.resolve(
options,
crudThrottleTime: crudThrottleTime,
// ignore: deprecated_member_use_from_same_package
retryDelay: retryDelay,
params: params,
);
// ignore: deprecated_member_use_from_same_package
clientParams = params;
var thisConnectAborter = AbortController();
final zone = Zone.current;
late void Function() retryHandler;
Future<void> connectWithSyncLock() async {
// Ensure there has not been a subsequent connect() call installing a new
// sync client.
assert(identical(_abortActiveSync, thisConnectAborter));
assert(!thisConnectAborter.aborted);
await connectInternal(
connector: connector,
options: resolvedOptions,
abort: thisConnectAborter,
// Run follow-up async tasks in the parent zone, a new one is introduced
// while we hold the lock (and async tasks won't hold the sync lock).
asyncWorkZone: zone,
);
thisConnectAborter.onCompletion.whenComplete(retryHandler);
}
// If the sync encounters a failure without being aborted, retry
retryHandler = Zone.current.bindCallback(() async {
_activeGroup.syncConnectMutex.lock(() async {
// Is this still supposed to be active? (abort is only called within
// mutex)
if (!thisConnectAborter.aborted) {
// We only change _abortActiveSync after disconnecting, which resets
// the abort controller.
assert(identical(_abortActiveSync, thisConnectAborter));
// We need a new abort controller for this attempt
_abortActiveSync = thisConnectAborter = AbortController();
logger.warning('Sync client failed, retrying...');
await connectWithSyncLock();
}
});
});
await _activeGroup.syncConnectMutex.lock(() async {
// Disconnect a previous sync client, if one is active.
await _abortCurrentSync();
assert(_abortActiveSync == null);
// Install the abort controller for this particular connect call, allowing
// it to be disconnected.
_abortActiveSync = thisConnectAborter;
await connectWithSyncLock();
});
}