Skip to content

Commit 2fb242d

Browse files
committed
HBASE-27563 ChaosMonkey sometimes generates invalid boundaries for random item selection
Signed-off-by: Duo Zhang <[email protected]>
1 parent b07b07f commit 2fb242d

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

hbase-it/src/test/java/org/apache/hadoop/hbase/chaos/monkies/PolicyBasedChaosMonkey.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@
3030
import org.apache.hadoop.hbase.IntegrationTestingUtility;
3131
import org.apache.hadoop.hbase.chaos.policies.Policy;
3232
import org.apache.hadoop.hbase.util.Pair;
33+
import org.apache.hadoop.hbase.util.ReservoirSample;
34+
import org.slf4j.Logger;
35+
import org.slf4j.LoggerFactory;
3336

3437
import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;
3538

3639
/**
3740
* Chaos monkey that given multiple policies will run actions against the cluster.
3841
*/
3942
public class PolicyBasedChaosMonkey extends ChaosMonkey {
43+
private static final Logger LOG = LoggerFactory.getLogger(PolicyBasedChaosMonkey.class);
4044

4145
private static final long ONE_SEC = 1000;
4246
private static final long ONE_MIN = 60 * ONE_SEC;
@@ -116,13 +120,14 @@ public static <T> T selectWeightedRandomItem(List<Pair<T, Integer>> items) {
116120

117121
/** Selects and returns ceil(ratio * items.length) random items from the given array */
118122
public static <T> List<T> selectRandomItems(T[] items, float ratio) {
119-
int selectedNumber = (int) Math.ceil(items.length * ratio);
120-
121-
List<T> originalItems = Arrays.asList(items);
122-
Collections.shuffle(originalItems);
123-
124-
int startIndex = ThreadLocalRandom.current().nextInt(items.length - selectedNumber);
125-
return originalItems.subList(startIndex, startIndex + selectedNumber);
123+
// clamp ratio to [0.0,1.0]
124+
ratio = Math.max(Math.min(ratio, 1.0f), 0.0f);
125+
final int selectedNumber = (int) Math.ceil(items.length * ratio);
126+
final ReservoirSample<T> sample = new ReservoirSample<>(selectedNumber);
127+
sample.add(Arrays.stream(items));
128+
final List<T> shuffledItems = sample.getSamplingResult();
129+
Collections.shuffle(shuffledItems);
130+
return shuffledItems;
126131
}
127132

128133
@Override
@@ -151,7 +156,10 @@ public boolean isStopped() {
151156

152157
@Override
153158
public void waitForStop() throws InterruptedException {
154-
monkeyThreadPool.awaitTermination(1, TimeUnit.MINUTES);
159+
if (!monkeyThreadPool.awaitTermination(1, TimeUnit.MINUTES)) {
160+
LOG.warn("Some pool threads failed to terminate. Forcing. {}", monkeyThreadPool);
161+
monkeyThreadPool.shutdownNow();
162+
}
155163
}
156164

157165
@Override

0 commit comments

Comments
 (0)