updateRoots method
Updates the list of roots by calling listRoots.
If the current _rootsCompleter
was not yet completed, then we wait to
complete it until we get an updated list of roots, so that we don't get
stale results from listRoots requests that are still in flight during
a change notification.
Implementation
@mustCallSuper
Future<void> updateRoots() async {
_rootsState = _RootsState.pending;
final previousCompleter = _rootsCompleter;
// Always create a new completer so we can handle race conditions by
// checking completer identity.
final newCompleter = _rootsCompleter = Completer();
_roots = null;
if (previousCompleter != null) {
// Complete previously scheduled completers with our completers value.
previousCompleter.complete(newCompleter.future);
}
ListRootsResult? result;
try {
result = await listRoots(ListRootsRequest());
} on RpcException catch (e) {
log(LoggingLevel.error, 'Error calling listRoots: $e');
} finally {
// Only complete the completer if it's still the one we created. Otherwise
// we wait for the next result to come back and throw away this result.
if (_rootsCompleter == newCompleter) {
final roots = result == null ? <Root>[] : result.roots;
newCompleter.complete(roots);
_roots = roots;
_rootsCompleter = null;
_rootsState = _RootsState.upToDate;
}
}
}