Skip to content

Commit 602dcf1

Browse files
committed
poolmanager: update wrandom partition to respect gap
Motivation: The wrandom partition ignores pool gap, thus can select a full pull. Issue: #7863 Modification: Update WRandomPartition to skip pools that will run into gap if accept the file. Added unit test to ensure the behavior. Result: full pulls are skipped by wrandom partition. Acked-by: Dmitry Litvintsev Target: master, 11.0, 10.2, 10.1, 10.0, 9.2 Require-book: no Require-notes: yes (cherry picked from commit a778f97) Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
1 parent a569bc6 commit 602dcf1

2 files changed

Lines changed: 78 additions & 3 deletions

File tree

‎modules/dcache/src/main/java/org/dcache/poolmanager/WRandomPartition.java‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,26 +84,44 @@ public SelectedPool selectStagePool(CostModule cm, List<PoolInfo> pools, Optiona
8484

8585
@Override
8686
public SelectedPool selectWritePool(CostModule cm, List<PoolInfo> pools, FileAttributes attributes, long preallocated) throws CacheException {
87-
WeightedPool weightedPools[] = toWeightedWritePoolsArray(pools);
87+
WeightedPool weightedPools[] = toWeightedWritePoolsArray(pools, preallocated);
88+
if (weightedPools.length == 0) {
89+
throw new CostException("All pools are full", null, false, false);
90+
}
8891
int index = selectWrandomIndex(weightedPools);
8992
return new SelectedPool(weightedPools[index].getCostInfo());
9093
}
9194

92-
private WeightedPool[] toWeightedWritePoolsArray(Collection<PoolInfo> costInfos) {
95+
private WeightedPool[] toWeightedWritePoolsArray(Collection<PoolInfo> costInfos, long fileSize)
96+
throws CacheException {
9397

9498
long totalFree = 0;
99+
int validCount = 0;
95100
for (PoolInfo costInfo : costInfos) {
101+
long gap = costInfo.getCostInfo().getSpaceInfo().getGap();
102+
96103
long spaceToUse = costInfo.getCostInfo().getSpaceInfo().getFreeSpace()
97104
+ costInfo.getCostInfo().getSpaceInfo().getRemovableSpace();
105+
if (fileSize > spaceToUse - gap) {
106+
continue; // skip pools that do not have enough space
107+
}
98108
totalFree += spaceToUse;
109+
validCount++;
99110
}
100111

101-
WeightedPool[] weightedPools = new WeightedPool[costInfos.size()];
112+
// the validCount should macht the number of pools that have enough space, thus elegible for selection
113+
WeightedPool[] weightedPools = new WeightedPool[validCount];
102114
int i = 0;
103115
for (PoolInfo costInfo : costInfos) {
116+
long gap = costInfo.getCostInfo().getSpaceInfo().getGap();
117+
104118
long spaceToUse = costInfo.getCostInfo().getSpaceInfo().getFreeSpace()
105119
+ costInfo.getCostInfo().getSpaceInfo().getRemovableSpace();
106120

121+
if (fileSize > spaceToUse - gap) {
122+
continue; // skip pools that do not have enough space
123+
}
124+
107125
weightedPools[i] = new WeightedPool(costInfo, (double) spaceToUse / totalFree);
108126
i++;
109127
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.dcache.poolmanager;
2+
3+
import com.google.common.collect.ImmutableMap;
4+
import diskCacheV111.pools.PoolCostInfo;
5+
import diskCacheV111.util.CacheException;
6+
import dmg.cells.nucleus.CellAddressCore;
7+
import org.hamcrest.MatcherAssert;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
import org.mockito.AdditionalMatchers;
11+
12+
import java.util.Map;
13+
import java.util.stream.IntStream;
14+
15+
import static org.junit.Assert.*;
16+
17+
public class WRandomPartitionTest {
18+
19+
20+
@Test(expected = CostException.class)
21+
public void shouldFailIfAllocatesIntoGap() throws CacheException {
22+
23+
var wrandom = new WRandomPartition(Map.of());
24+
var pools = IntStream.range(0, 10).mapToObj(i -> {
25+
var cost = new PoolCostInfo("pool" + i, "default-queue");
26+
cost.setSpaceUsage(10_000L, 3000L, 0L, 0L);
27+
cost.getSpaceInfo().setParameter(0.0d, 2500L);
28+
29+
return new PoolInfo(new CellAddressCore("pool" + i), cost, ImmutableMap.of());
30+
}
31+
).toList();
32+
33+
long fileSize = 1000L;
34+
var selectedPool = wrandom.selectWritePool(null, pools, null, fileSize);
35+
}
36+
37+
@Test
38+
public void shouldSelectValidPool() throws CacheException {
39+
40+
var wrandom = new WRandomPartition(Map.of());
41+
var pools = IntStream.range(0, 10).mapToObj(i -> {
42+
var cost = new PoolCostInfo("pool" + i, "default-queue");
43+
cost.setSpaceUsage(10_000L, 5000L, 0L, 0L);
44+
cost.getSpaceInfo().setParameter(0.0d, 2500L);
45+
46+
return new PoolInfo(new CellAddressCore("pool" + i), cost, ImmutableMap.of());
47+
}
48+
).toList();
49+
50+
long fileSize = 1000L;
51+
var selectedPool = wrandom.selectWritePool(null, pools, null, fileSize);
52+
53+
var spaceInfo = selectedPool.info().getCostInfo().getSpaceInfo();
54+
assertTrue("selected pool has no sufficient space", spaceInfo.getFreeSpace() + spaceInfo.getRemovableSpace() - fileSize > spaceInfo.getGap());
55+
}
56+
57+
}

0 commit comments

Comments
 (0)