Skip to content

Commit 25b452b

Browse files
ghislainpiotsonartech
authored andcommitted
SONARPY-2764 Add analysis property to change number of threads or disable parallel (#221)
GitOrigin-RevId: 0ce2700c26e08a73c9af2dfad8d1957c3a87efda
1 parent 2b66d9d commit 25b452b

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

python-commons/src/main/java/org/sonar/plugins/python/PythonScanner.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public class PythonScanner extends Scanner {
7676

7777
private static final Logger LOG = LoggerFactory.getLogger(PythonScanner.class);
7878
private static final Pattern DATABRICKS_MAGIC_COMMAND_PATTERN = Pattern.compile("^\\h*#\\h*(MAGIC|COMMAND).*");
79+
public static final String THREADS_PROPERTY_NAME = "sonar.python.analysis.threads";
7980

8081
private final Supplier<PythonParser> parserSupplier;
8182
private final PythonChecks checks;
@@ -113,8 +114,14 @@ protected String name() {
113114
@Override
114115
protected void processFiles(List<PythonInputFile> files, SensorContext context, MultiFileProgressReport progressReport,
115116
AtomicInteger numScannedWithoutParsing) {
116-
ForkJoinPool pool = new ForkJoinPool(1);
117+
var numberOfThreads = getNumberOfThreads(context);
118+
if (numberOfThreads == 1) {
119+
super.processFiles(files, context, progressReport, numScannedWithoutParsing);
120+
return;
121+
}
122+
var pool = new ForkJoinPool(numberOfThreads);
117123
try {
124+
LOG.debug("Scanning files in {} threads", numberOfThreads);
118125
pool.submit(() -> super.processFiles(files, context, progressReport, numScannedWithoutParsing))
119126
.join();
120127
} finally {
@@ -124,7 +131,7 @@ protected void processFiles(List<PythonInputFile> files, SensorContext context,
124131

125132
@Override
126133
protected Stream<PythonInputFile> getFilesStream(List<PythonInputFile> files) {
127-
return files.stream().parallel();
134+
return getNumberOfThreads(context) == 1 ? files.stream() : files.stream().parallel();
128135
}
129136

130137
@Override
@@ -451,4 +458,9 @@ public int getRecognitionErrorCount() {
451458
public boolean getFoundDatabricks() {
452459
return foundDatabricks.get();
453460
}
461+
462+
private static Integer getNumberOfThreads(SensorContext context) {
463+
return context.config().getInt(THREADS_PROPERTY_NAME)
464+
.orElse(1);
465+
}
454466
}

python-commons/src/test/java/org/sonar/plugins/python/PythonSensorTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,9 @@ void test_symbol_visitor() {
345345
verifyUsages(key, 47, 5, reference(48, 14, 48, 17));
346346
}
347347

348-
@Test
349-
void test_issues() {
348+
@ParameterizedTest
349+
@ValueSource(ints = {1, 2})
350+
void test_issues(int threads) {
350351
activeRules = new ActiveRulesBuilder()
351352
.addRule(new NewActiveRule.Builder()
352353
.setRuleKey(RuleKey.of(PythonRuleRepository.REPOSITORY_KEY, ONE_STATEMENT_PER_LINE_RULE_KEY))
@@ -361,6 +362,7 @@ void test_issues() {
361362
.build();
362363

363364
PythonInputFile inputFile = inputFile(FILE_2);
365+
context.settings().setProperty(PythonScanner.THREADS_PROPERTY_NAME, String.valueOf(threads));
364366
sensor().execute(context);
365367

366368
assertThat(context.allIssues()).hasSize(3);
@@ -404,7 +406,11 @@ void test_issues() {
404406
assertThat(logTester.logs(Level.INFO)).contains("Starting global symbols computation");
405407
assertThat(logTester.logs(Level.INFO)).contains("Starting rules execution");
406408
assertThat(logTester.logs(Level.INFO).stream().filter(line -> line.equals("1 source file to be analyzed")).count()).isEqualTo(2);
407-
409+
if (threads == 1) {
410+
assertThat(logTester.logs(Level.DEBUG)).doesNotContain("Scanning files in");
411+
} else {
412+
assertThat(logTester.logs(Level.DEBUG)).contains("Scanning files in " + threads + " threads");
413+
}
408414
assertThat(PythonScanner.getWorkingDirectory(context)).isEqualTo(workDir.toFile());
409415
}
410416

0 commit comments

Comments
 (0)