tomWithFileLockAsync<T> function
tomWithFileLock for a caller that must not block its isolate while it
waits: the waits between attempts are Future.delayed, and body may be
asynchronous.
The exclusion is the same guard file, so it holds against every other
holder of lockFile — another asynchronous task on this isolate as much as
another isolate or process: the second task's exclusive create fails while
the first holds the guard, exactly as a foreign process's would. Between
the awaits of body the isolate runs other code, and that is the price of
not blocking: code that must not run inside the critical section has to
take the same guard to be kept out.
Implementation
Future<T> tomWithFileLockAsync<T>(
File lockFile,
Future<T> Function() body, {
Duration staleAfter = tomFileLockStaleAfter,
Duration timeout = const Duration(seconds: 30),
void Function(String warning)? onBrokenLock,
}) async {
final token = _newToken();
final deadline = DateTime.now().add(timeout);
while (!_attempt(lockFile, token, staleAfter, onBrokenLock)) {
_failIfPast(deadline, lockFile, timeout);
await Future<void>.delayed(_retryInterval);
}
try {
return await body();
} finally {
_release(lockFile, token);
}
}