HBASE-19709 Ensure that we don't set a poolSize of 0
In some situations, Runtime.getRuntime().getAvailableProcessors() may return 0 which would result in calculatePoolSize returning 0 which will trigger an exception. Guard against this case. Signed-off-by: Reid Chan <reidddchan@outlook.com> Signed-off-by: Chia-Ping Tsai <chia7712@gmail.com> Signed-off-by: Ted Yu <yuzhihong@gmail.com>
This commit is contained in:
parent
ce80e8e38f
commit
443b27b707
|
@ -119,7 +119,7 @@ public abstract class CleanerChore<T extends FileCleanerDelegate> extends Schedu
|
||||||
* @param poolSize size from configuration
|
* @param poolSize size from configuration
|
||||||
* @return size of pool after calculation
|
* @return size of pool after calculation
|
||||||
*/
|
*/
|
||||||
private int calculatePoolSize(String poolSize) {
|
int calculatePoolSize(String poolSize) {
|
||||||
if (poolSize.matches("[1-9][0-9]*")) {
|
if (poolSize.matches("[1-9][0-9]*")) {
|
||||||
// If poolSize is an integer, return it directly,
|
// If poolSize is an integer, return it directly,
|
||||||
// but upmost to the number of available processors.
|
// but upmost to the number of available processors.
|
||||||
|
@ -130,7 +130,13 @@ public abstract class CleanerChore<T extends FileCleanerDelegate> extends Schedu
|
||||||
return size;
|
return size;
|
||||||
} else if (poolSize.matches("0.[0-9]+|1.0")) {
|
} else if (poolSize.matches("0.[0-9]+|1.0")) {
|
||||||
// if poolSize is a double, return poolSize * availableProcessors;
|
// if poolSize is a double, return poolSize * availableProcessors;
|
||||||
return (int) (AVAIL_PROCESSORS * Double.valueOf(poolSize));
|
// Ensure that we always return at least one.
|
||||||
|
int computedThreads = (int) (AVAIL_PROCESSORS * Double.valueOf(poolSize));
|
||||||
|
if (computedThreads < 1) {
|
||||||
|
LOG.debug("Computed {} threads for CleanerChore, using 1 instead", computedThreads);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return computedThreads;
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Unrecognized value: " + poolSize + " for " + CHORE_POOL_SIZE +
|
LOG.error("Unrecognized value: " + poolSize + " for " + CHORE_POOL_SIZE +
|
||||||
", use default config: " + DEFAULT_CHORE_POOL_SIZE + " instead.");
|
", use default config: " + DEFAULT_CHORE_POOL_SIZE + " instead.");
|
||||||
|
|
|
@ -388,6 +388,25 @@ public class TestCleanerChore {
|
||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMinimumNumberOfThreads() throws Exception {
|
||||||
|
Stoppable stop = new StoppableImplementation();
|
||||||
|
Configuration conf = UTIL.getConfiguration();
|
||||||
|
Path testDir = UTIL.getDataTestDir();
|
||||||
|
FileSystem fs = UTIL.getTestFileSystem();
|
||||||
|
String confKey = "hbase.test.cleaner.delegates";
|
||||||
|
conf.set(confKey, AlwaysDelete.class.getName());
|
||||||
|
conf.set(CleanerChore.CHORE_POOL_SIZE, "2");
|
||||||
|
AllValidPaths chore = new AllValidPaths("test-file-cleaner", stop, conf, fs, testDir, confKey);
|
||||||
|
int numProcs = Runtime.getRuntime().availableProcessors();
|
||||||
|
// Sanity
|
||||||
|
assertEquals(numProcs, chore.calculatePoolSize(Integer.toString(numProcs)));
|
||||||
|
// The implementation does not allow us to set more threads than we have processors
|
||||||
|
assertEquals(numProcs, chore.calculatePoolSize(Integer.toString(numProcs + 2)));
|
||||||
|
// Force us into the branch that is multiplying 0.0 against the number of processors
|
||||||
|
assertEquals(1, chore.calculatePoolSize("0.0"));
|
||||||
|
}
|
||||||
|
|
||||||
private void createFiles(FileSystem fs, Path parentDir, int numOfFiles) throws IOException {
|
private void createFiles(FileSystem fs, Path parentDir, int numOfFiles) throws IOException {
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
for (int i = 0; i < numOfFiles; i++) {
|
for (int i = 0; i < numOfFiles; i++) {
|
||||||
|
|
Loading…
Reference in New Issue