1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.invoker;
20
21 import java.util.LinkedHashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.ExecutorService;
26 import java.util.concurrent.Executors;
27 import java.util.stream.Collectors;
28
29 import org.apache.maven.plugins.invoker.model.BuildJob;
30
31
32
33
34
35
36 class JobExecutor {
37 interface ThrowableJobConsumer {
38 void accept(BuildJob t) throws Throwable;
39 }
40
41 private final List<BuildJob> jobs;
42 private final int threadsCount;
43
44 JobExecutor(List<BuildJob> jobs, int threadsCount) {
45 this.jobs = jobs;
46 this.threadsCount = threadsCount;
47 }
48
49 public void forEach(ThrowableJobConsumer jobConsumer) {
50
51 Map<Integer, List<BuildJob>> groupedJobs = jobs.stream()
52 .sorted((j1, j2) -> Integer.compare(j2.getOrdinal(), j1.getOrdinal()))
53 .collect(Collectors.groupingBy(BuildJob::getOrdinal, LinkedHashMap::new, Collectors.toList()));
54
55 ExecutorService executorService = Executors.newFixedThreadPool(threadsCount);
56
57 groupedJobs.forEach((key, value) -> {
58
59 List<Callable<Void>> callableJobs = value.stream()
60 .map(buildJob -> (Callable<Void>) () -> {
61 try {
62 jobConsumer.accept(buildJob);
63 } catch (Throwable e) {
64 buildJob.setResult(BuildJob.Result.ERROR);
65 buildJob.setFailureMessage(String.valueOf(e));
66 }
67 return null;
68 })
69 .collect(Collectors.toList());
70
71 try {
72 executorService.invokeAll(callableJobs);
73 } catch (InterruptedException e) {
74 Thread.currentThread().interrupt();
75 throw new RuntimeException(e);
76 }
77 });
78
79
80 executorService.shutdownNow();
81 }
82 }