detach static method
Detaches the Context associated with the given ContextToken
from their
associated Zone.
Returns true
if the given ContextToken
is associated with the latest,
expected, attached Context, false
otherwise.
If the ContextToken
is not found in the latest stack, detach will walk up
the Zone tree attempting to find and detach the associated Context.
Regardless of whether the Context is found, if the given ContextToken
is
not expected, a warning will be logged.
Implementation
@experimental
static bool detach(ContextToken token, [Zone? zone]) {
final stack = _currentContextStack(zone ?? Zone.current);
final index = stack.indexWhere((c) => c.token == token);
// the expected context to detach is the latest entry of the latest stack
final match = index != -1 && index == stack.length - 1;
if (!match) {
_log.warning('unexpected (mismatched) token given to detach');
}
if (index != -1) {
// context found in the latest stack, possibly the latest entry
stack.removeAt(index);
return match;
}
// at this point, the token was not in the latest stack, but it might be in a
// stack held by a parent zone
// walk up the zone tree checking for the token in each zone's context stack
zone ??= Zone.current;
do {
final stack = _stacks[zone!];
final index = stack?.indexWhere((c) => c.token == token);
if (index != null && index != -1) {
// token found, remove it, but return false since it wasn't expected
stack!.removeAt(index);
return false;
}
zone = zone.parent;
} while (zone != null);
// the token was nowhere to be found, a context was not detached
_log.warning('failed to detach context');
return false;
}