scratchSpaceResource top-level property
Resource<ScratchSpace>
scratchSpaceResource
final
A shared Resource
for a ScratchSpace
, which cleans up the contents of
the ScratchSpace
in dispose, but doesn't delete it entirely.
Implementation
final scratchSpaceResource = Resource<ScratchSpace>(() {
if (!scratchSpace.exists) {
scratchSpace.tempDir.createSync(recursive: true);
scratchSpace.exists = true;
}
var packageConfigFile = File(
p.join(scratchSpace.tempDir.path, '.dart_tool', 'package_config.json'));
if (!packageConfigFile.existsSync()) {
var originalConfigFile = File(p.join('.dart_tool', 'package_config.json'));
var packageConfigContents = _scratchSpacePackageConfig(
originalConfigFile.readAsStringSync(), originalConfigFile.absolute.uri);
packageConfigFile
..createSync(recursive: true)
..writeAsStringSync(packageConfigContents);
}
return scratchSpace;
}, beforeExit: () async {
// The workers are running inside the scratch space, so wait for them to
// shut down before deleting it.
await dartdevkWorkersAreDone;
await frontendWorkersAreDone;
// Attempt to clean up the scratch space. Even after waiting for the workers
// to shut down we might get file system exceptions on windows for an
// arbitrary amount of time, so do retries with an exponential backoff.
var numTries = 0;
while (true) {
numTries++;
if (numTries > 3) {
_logger
.warning('Failed to clean up temp dir ${scratchSpace.tempDir.path}.');
return;
}
try {
// TODO(https://github.com/dart-lang/build/issues/656): The scratch
// space throws on `delete` if it thinks it was already deleted.
// Manually clean up in this case.
if (scratchSpace.exists) {
await scratchSpace.delete();
} else {
await scratchSpace.tempDir.delete(recursive: true);
}
return;
} on FileSystemException {
var delayMs = math.pow(10, numTries).floor();
_logger.info('Failed to delete temp dir ${scratchSpace.tempDir.path}, '
'retrying in ${delayMs}ms');
await Future<void>.delayed(Duration(milliseconds: delayMs));
}
}
});