in src/main/java/build/buildfarm/cas/cfc/CASFileCache.java [2450:2522]
private boolean charge(String key, long blobSizeInBytes, AtomicBoolean requiresDischarge)
throws IOException, InterruptedException {
boolean interrupted = false;
Iterable<ListenableFuture<Digest>> expiredDigestsFutures;
synchronized (this) {
if (referenceIfExists(key)) {
return false;
}
sizeInBytes += blobSizeInBytes;
requiresDischarge.set(true);
ImmutableList.Builder<ListenableFuture<Digest>> builder = ImmutableList.builder();
try {
while (!interrupted && sizeInBytes > maxSizeInBytes) {
ListenableFuture<Entry> expiredFuture = expireEntry(blobSizeInBytes, expireService);
interrupted = Thread.interrupted();
if (expiredFuture != null) {
builder.add(
transformAsync(
expiredFuture,
(expiredEntry) -> {
String expiredKey = expiredEntry.key;
try {
Files.delete(getPath(expiredKey));
} catch (NoSuchFileException eNoEnt) {
logger.log(
Level.SEVERE,
format(
"CASFileCache::putImpl: expired key %s did not exist to delete",
expiredKey));
}
FileEntryKey fileEntryKey = parseFileEntryKey(expiredKey, expiredEntry.size);
if (fileEntryKey == null) {
logger.log(
Level.SEVERE, format("error parsing expired key %s", expiredKey));
} else if (storage.containsKey(
getKey(fileEntryKey.getDigest(), !fileEntryKey.getIsExecutable()))) {
return immediateFuture(null);
}
expiredKeyCounter.inc();
logger.log(Level.INFO, format("expired key %s", expiredKey));
return immediateFuture(fileEntryKey.getDigest());
},
expireService));
}
}
} catch (InterruptedException e) {
// clear interrupted flag
Thread.interrupted();
interrupted = true;
}
expiredDigestsFutures = builder.build();
}
ImmutableSet.Builder<Digest> builder = ImmutableSet.builder();
for (ListenableFuture<Digest> expiredDigestFuture : expiredDigestsFutures) {
Digest digest = getOrIOException(expiredDigestFuture);
if (Thread.interrupted()) {
interrupted = true;
}
if (digest != null) {
builder.add(digest);
}
}
Set<Digest> expiredDigests = builder.build();
if (!expiredDigests.isEmpty()) {
onExpire.accept(expiredDigests);
}
if (interrupted || Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
return true;
}