Skip to content

Commit c21aec9

Browse files
committed
#22 done
1 parent 77d4149 commit c21aec9

File tree

3 files changed

+61
-66
lines changed

3 files changed

+61
-66
lines changed

src/main/groovy/repo/build/maven/Build.groovy

Lines changed: 58 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,28 @@ import groovy.transform.CompileStatic
44
import repo.build.ActionContext
55
import repo.build.ComponentDependencyGraph
66
import repo.build.Maven
7-
import repo.build.MavenFeature
87
import repo.build.RepoBuildException
98

10-
import java.util.concurrent.ForkJoinPool
11-
import java.util.concurrent.RecursiveTask
9+
import java.util.concurrent.ConcurrentHashMap
10+
import java.util.concurrent.ConcurrentMap
11+
import java.util.concurrent.Executors
1212

1313
/**
1414
* @author Markelov Ruslan markelov@jet.msk.su
1515
*/
1616
//@CompileStatic
1717
class Build {
18-
Map<MavenArtifactRef, MavenComponent> componentMap
19-
Map<MavenArtifactRef, BuildTask> buildTaskMap
18+
Collection<MavenComponent> components
2019
ActionContext context
21-
Map<MavenArtifactRef, MavenComponent> moduleToComponentMap
2220

23-
Build(ActionContext context, List<MavenComponent> components) {
21+
Build(ActionContext context, Collection<MavenComponent> components) {
2422
this.context = context
25-
this.componentMap = components.collectEntries {
26-
[new MavenArtifactRef(it), it]
27-
}
28-
this.moduleToComponentMap = ComponentDependencyGraph
29-
.getModuleToComponentMap(components)
30-
31-
this.buildTaskMap = componentMap.collectEntries {
32-
[it.key, new BuildTask(it.value)]
33-
} as Map<MavenArtifactRef, BuildTask>
23+
this.components = components
3424
}
3525

3626
boolean execute(ActionContext context) {
3727
// check circular dependencies
38-
def graph = ComponentDependencyGraph.build(componentMap.values())
28+
def graph = ComponentDependencyGraph.build(components)
3929
if (graph.hasCycles()) {
4030
for (def entry : graph.cycleRefs) {
4131
def component = entry.getKey()
@@ -44,62 +34,66 @@ class Build {
4434
}
4535
throw new RepoBuildException("project has circular dependencies")
4636
}
47-
// do parallel build
48-
def pool = new ForkJoinPool(context.getParallel())
49-
return pool.invoke(new RecursiveTask<Boolean>() {
50-
@Override
51-
protected Boolean compute() {
52-
// execute all build tasks
53-
buildTaskMap.each { pool.execute(it.value) }
54-
// wait build for all components
55-
return !componentMap
56-
.collect { buildTaskMap.get(it.key).join() }
57-
.any { it != BuildState.SUCCESS }
58-
}
59-
})
60-
}
61-
62-
//@CompileStatic
63-
private class BuildTask extends RecursiveTask<BuildState> {
64-
MavenComponent component
65-
BuildState state
6637

67-
BuildTask(MavenComponent component) {
68-
this.component = component
38+
Map<MavenArtifactRef, MavenComponent> componentMap = components.collectEntries {
39+
[new MavenArtifactRef(it), it]
6940
}
7041

71-
protected BuildState compute() {
72-
println("build component $component.path")
73-
// wait build deps
74-
def isFail = component
75-
.getModules()
42+
Map<MavenArtifactRef, BuildState> buildStates = componentMap.collectEntries {
43+
[it.key, BuildState.NEW]
44+
} as Map<MavenArtifactRef, BuildState>
45+
46+
Map<MavenArtifactRef, MavenComponent> moduleToComponentMap =
47+
ComponentDependencyGraph.getModuleToComponentMap(components)
48+
49+
ConcurrentMap<MavenArtifactRef, List<MavenArtifactRef>> buildDeps = new ConcurrentHashMap<>()
50+
buildStates.keySet().forEach { MavenArtifactRef key ->
51+
def depsTasks = componentMap.get(key).modules
7652
.collectMany { it.dependencies }
7753
.findAll { moduleToComponentMap.containsKey(it) }
7854
.unique()
7955
.collect { new MavenArtifactRef(moduleToComponentMap.get(it)) }
80-
.collect { buildTaskMap.get(it) }
81-
.findAll { it != this }
82-
.collect { println("wait build $it.component.path"); it.join() }
83-
.any { it != BuildState.SUCCESS }
84-
if (isFail) {
85-
state = BuildState.DEPS_ERROR
86-
context.setErrorFlag()
87-
context.addError(new RepoBuildException(" component ${component.path} build $state"))
88-
} else {
89-
// build component
90-
try {
91-
def pomFile = new File(component.basedir, 'pom.xml')
92-
def p = new Properties()
93-
Maven.execute(context, pomFile, ['clean', 'install'])
94-
state = BuildState.SUCCESS
95-
} catch (Exception e) {
96-
state = BuildState.ERROR
56+
.findAll { !key.equals(it) }
57+
buildDeps.put(key, depsTasks)
58+
return
59+
}
60+
61+
Set<MavenArtifactRef> tasks = new HashSet<>(buildStates.keySet())
62+
63+
def pool = Executors.newFixedThreadPool(context.getParallel())
64+
while (!tasks.isEmpty()) {
65+
def iter = tasks.iterator()
66+
while (iter.hasNext()) {
67+
def key = iter.next()
68+
def component = componentMap.get(key)
69+
def deps = buildDeps.get(key)
70+
if (!deps.any { buildStates.get(it) != BuildState.SUCCESS }) {
71+
pool.execute {
72+
// build component
73+
try {
74+
def pomFile = new File(component.basedir, 'pom.xml')
75+
Maven.execute(context, pomFile, ['clean', 'install'])
76+
buildStates.put(key, BuildState.SUCCESS)
77+
} catch (Exception e) {
78+
buildStates.put(key, BuildState.ERROR)
79+
context.setErrorFlag()
80+
context.addError(new RepoBuildException(" component ${component.path} build ERROR", e))
81+
}
82+
}
83+
iter.remove()
84+
} else if (deps.any {
85+
buildStates.get(it) == BuildState.DEPS_ERROR ||
86+
buildStates.get(it) == BuildState.ERROR
87+
}) {
88+
buildStates.put(key, BuildState.DEPS_ERROR)
9789
context.setErrorFlag()
98-
context.addError(new RepoBuildException(" component ${component.path} build $state", e))
90+
context.addError(new RepoBuildException(" component ${component.path} build DEPS_ERROR"))
91+
iter.remove()
9992
}
10093
}
101-
return state
94+
// throttle cpu
95+
Thread.sleep(500L)
10296
}
97+
return !context.getErrorFlag()
10398
}
104-
105-
}
99+
}

src/main/groovy/repo/build/maven/BuildState.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* @author Markelov Ruslan markelov@jet.msk.su
55
*/
66
public enum BuildState {
7+
NEW,
78
SUCCESS,
89
ERROR,
910
DEPS_ERROR

src/test/groovy/repo/build/BaseTestCase.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ abstract class BaseTestCase extends GroovyAssert {
2121
context = new ActionContext(env, null, options, new DefaultActionHandler())
2222
}
2323

24-
String getArgs() {
25-
return "-j 4"
24+
String[] getArgs() {
25+
return ["-j", "4"]
2626
}
2727

2828
static File createTempDir() {

0 commit comments

Comments
 (0)