setPrincipal method
Declares who the cached data belongs to, dropping everything on a change. Watched queries are re-mounted and refetched; their in-flight requests are abandoned. Every running sync source's context is fenced before anything is dropped; the sources themselves stop in the background, and idle completes once they have.
Listeners told of the change (a changing listener, a watcher told of the clear, a watchPrincipal listener) must not call setPrincipal or clear. If one does, that call runs to completion and this one stops where it is: the later principal is the one left in charge, and the superseded one is neither started nor announced.
Implementation
void setPrincipal(String? principal) {
if (principal == _principal) return;
_principal = principal;
// Before the clear, synchronously: from here on the store is the next
// principal's, and a write the old sources make while they stop must not
// land in it.
_deactivateContexts();
// Before the clear, whose notifications would otherwise carry the old
// principal's sync status to the new principal's watchers.
_detachStatuses();
// Before the clear, whose notifications are the first thing a watcher
// sees of the new principal; see watchPrincipalChanging.
for (final listener in _principalsChanging.toList()) {
// A listener called setPrincipal itself (see below).
if (_principal != principal) return;
try {
listener(principal);
} on Object catch (error) {
_onError?.call(error, 'principal');
}
}
if (_principal != principal) return;
_clear(keepOwned: false);
// A listener told of the clear called setPrincipal, or one did after it.
// That call ran its own transition to completion, so this one stops:
// starting this principal's sources and session, or announcing it, would
// put a superseded principal in charge after the current one. Listeners
// must not call setPrincipal or clear, but the cache stays consistent if
// one does.
if (_principal != principal) return;
_scheduleSync(principal);
for (final listener in _principals.toList()) {
if (_principal != principal) return;
try {
listener(principal);
} on Object catch (error) {
_onError?.call(error, 'principal');
}
}
if (_principal != principal) return;
if (!_principalChanges.isClosed) _principalChanges.add(principal);
}