in server/src/jetbrains/buildServer/sharedResources/server/runtime/TakenLocksImpl.java [197:262]
private void checkAgainstCustomResource(@NotNull final Lock lock,
@NotNull final Map<Resource, TakenLock> takenLocks,
@NotNull final CustomResource resource,
@NotNull final DistributionDataAccessor distributionDataAccessor,
@NotNull final BuildPromotion buildPromotion,
@NotNull final Map<Resource, String> result) {
// what type of lock do we have:
// write -> all
// read with value -> specific
// read -> any
final TakenLock takenLock = getOrCreateTakenLock(takenLocks, resource);
switch (lock.getType()) {
case READ: // check at least one value is available
// check for unique writeLocks
List<BuildPromotion> promosInFairSet = distributionDataAccessor.getFairSet().get(resource.getId());
if (promosInFairSet != null && !promosInFairSet.isEmpty()) {
String description = describeLockingPromotions(promosInFairSet);
result.put(resource, "(write lock requested by " + description + ")");
break;
}
// check for write locks
if (takenLock.hasWriteLocks()) {
// write lock can be in chain head, read locks can be in chain parts
String description = describeLockingPromotions(takenLock.getReadLocks().keySet(), takenLock.getWriteLocks().keySet());
result.put(resource, "(locked by " + description + ")");
break;
}
// 2) SPECIFIC case
if (!lock.isAnyValueLock()) { // we have custom lock
final String requiredValue = lock.getValue();
final Set<String> takenValues = new HashSet<>();
takenValues.addAll(takenLock.getReadLocks().values());
takenValues.addAll(takenLock.getWriteLocks().values());
takenValues.addAll(distributionDataAccessor.getReservedValuesProvider().getReservedValues(resource).values());
if (takenValues.contains(requiredValue)) {
StringBuilder builder = new StringBuilder("(required value '" + requiredValue + "' is occupied");
BuildPromotionEx occupyingPromo = occupyingPromo(takenLock, requiredValue);
if (occupyingPromo != null) {
String description = describeLockingPromotions(Collections.singleton(occupyingPromo));
builder.append(" by ");
builder.append(description);
}
builder.append(")");
result.put(resource, builder.toString());
break;
}
}
// 3) check for any unoccupied value
if (resource.getValues().size() <= takenLock.getLocksCount()) {
String description = describeLockingPromotions(takenLock.getReadLocks().keySet());
result.put(resource, "(all available values are occupied by " + description + ")");
break;
// quota exceeded
}
break;
case WRITE:
// 'ALL' case
if (takenLock.hasReadLocks() || takenLock.hasWriteLocks()) {
addToFairSet(distributionDataAccessor, resource, buildPromotion);
String description = describeLockingPromotions(takenLock.getReadLocks().keySet(), takenLock.getWriteLocks().keySet());
result.put(resource, "(locked by " + description + ")");
break;
}
break;
}
}