in server/src/jetbrains/buildServer/sharedResources/server/runtime/LocksStorageImpl.java [70:120]
public LocksStorageImpl(@NotNull final EventDispatcher<BuildServerListener> dispatcher) {
CacheLoader<BuildPromotion, Map<String, Lock>> loader = new CacheLoader<BuildPromotion, Map<String, Lock>>() {
@Override
public Map<String, Lock> load(@NotNull final BuildPromotion buildPromotion) {
final Map<String, Lock> result;
final File artifact = new File(buildPromotion.getArtifactsDirectory(), FILE_PATH);
if (artifact.exists()) {
result = new HashMap<>();
try {
final String content = FileUtil.readText(artifact, MY_ENCODING);
final String[] lines = StringUtil.splitLines(content);
for (String line : lines) {
final Lock lock = deserializeTakenLock(line);
if (lock != null) {
result.put(lock.getName(), lock);
} else {
if (log.isDebugEnabled()) {
log.debug("Wrong locks storage format in file {" + artifact.getAbsolutePath() + "} line: {" + line + "}");
}
}
}
} catch (IOException e) {
log.warn("Failed to load taken locks for build [" + buildPromotion + "]; Message is: " + e.getMessage());
}
} else {
result = Collections.emptyMap();
}
return result;
}
};
myLocksCache = CacheBuilder.newBuilder()
.maximumSize(TeamCityProperties.getInteger("teamcity.sharedResources.locksStorage.cacheSize", 300)) // each entry corresponds to a running build
.build(loader);
dispatcher.addListener(new BuildServerAdapter() {
@Override
public void buildFinished(@NotNull SRunningBuild build) {
withLock(buildPromotionLock(build.getBuildPromotion()),
() -> {
withLock(myGlobalLock::writeLock,
() -> {
myLocksCache.invalidate(build.getBuildPromotion());
existsSet.remove(build.getBuildPromotion().getId());
return null;
});
return null;
});
}
});
}