tryAcquire static method
Takes the lock on project, or returns null when another change holds
it. Throws a FileSystemException when the lock can't be made at all
(a read-only folder, a path too long).
Implementation
static ProjectLock? tryAcquire(JustProject project) {
final file = project.file(path);
file.parent.createSync(recursive: true);
final token = _newToken();
for (var attempt = 1; ; attempt++) {
try {
file.createSync(exclusive: true);
} on FileSystemException catch (e) {
final held = _Holder.read(file);
if (held == null) {
// Released in between — or the file can't be made at all.
if (attempt < 3) continue;
throw FileSystemException(
'Could not make the project lock',
file.path,
e.osError,
);
}
if (DateTime.now().difference(held.touched) <= stale &&
!_crashedHere(held)) {
return null;
}
// Left by a crash: out of the way with it, then try again.
if (attempt >= 3) return null;
_takeOver(file, held, token);
continue;
}
try {
file.writeAsStringSync(
jsonEncode({
'pid': pid,
..._here,
'token': token,
'since': DateTime.now().toUtc().toIso8601String(),
}),
flush: true,
);
} on FileSystemException {
try {
file.deleteSync();
} on FileSystemException {
// It goes stale on its own.
}
rethrow;
}
return ProjectLock._(file, token);
}
}