-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maven-like rolling output when the build happens to be linear #271
Conversation
session.getRequest().getDegreeOfConcurrency())); | ||
|
||
final DependencyGraph smartGraph = DependencyGraph.fromMaven(session); | ||
session.setProjectDependencyGraph(smartGraph); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gnodet this is quite a rough way to do it. I was not able to persuade the guice container to prefer my org.apache.maven.graph.GraphBuilder impl. to the default one. So I gave up and did this replacement instead. I would not mind if you veto this and propose something more elegant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If so, it may be better to not rewrite the graph and just keep the code as it is.
i.e. DependencyGraph and not tie it to ProjectDependencyGraph.
I am a bit more content with 385d77e:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit more content with 385d77e:
- Our custom SmartGraphBuilder is properly instantiated via Guice
- The DependencyGraph now has a width field, that returns 1 if the graph is serial and Integer.MAX_VALUE otherwise. That's enough for the current feature. It can be enhanced later to return the proper width for other purposes.
Would it be possible to keep the DependencyGraph interface independent of maven ? The algorithm I have only depends on the upstream / downstream methods, so having to create MavenProject objects for nothing will make things harder to test.
public Stream<MavenProject> getDownstreamProjects(MavenProject project) { | ||
return downstreams.get(project).stream(); | ||
} | ||
final boolean serial = !projects.stream().anyMatch(p -> downstreams.get(p).size() > 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check isn't correct imho. In order to use such a check, we'd have to remove dependencies that are redundant. For example
A depends on B
A depends on C
B depends on C
This is a very common scenario (C being the parent, with 2 children), but I think it will fail the check because C will have 2 downstream projects, yet, the build is linear (C -> B -> A).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, is there any case where it returns 1 apart when building a single project ? It looks like the parent/child relationship will make this simple algorithm useless. Am I missing something ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it is not perfect, but it works in some simple cases at least and for me it is still an important improvement. As I said, a proper width computation can be added later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can easily port my computation algorithm, provided you keep the DependencyGraph<K>
interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've rebased on master. The computation can be done using the following lines: https://github.com/gnodet/mvnd/blob/d77d1f777b5bdba4697d8afaadef730813af81ce/daemon/src/main/java/org/mvndaemon/mvnd/builder/SmartBuilder.java#L200-L203
|
||
final int maxThreads = smartGraph.isSerial() ? 1 : session.getRequest().getDegreeOfConcurrency(); | ||
queue.add(new BuildStarted(getCurrentProject(session).getName(), smartGraph.getSortedProjects().size(), | ||
maxThreads)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a branch pending that attempts at computing the maximum width of the graph, let me check its state.
session.getRequest().getDegreeOfConcurrency())); | ||
|
||
final DependencyGraph smartGraph = DependencyGraph.fromMaven(session); | ||
session.setProjectDependencyGraph(smartGraph); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If so, it may be better to not rewrite the graph and just keep the code as it is.
i.e. DependencyGraph and not tie it to ProjectDependencyGraph.
@@ -173,6 +173,11 @@ private boolean doAccept(Message entry) { | |||
this.maxThreads = bs.getMaxThreads(); | |||
final int maxThreadsDigits = (int) (Math.log10(maxThreads) + 1); | |||
this.threadsFormat = "%" + (maxThreadsDigits * 3 + 2) + "s"; | |||
if (maxThreads == 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use a configuration flag for that ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean some users might not want this auto-rolling? I must say I like it like this. I would not want to add the flag unless somebody explicitly asks for it. Of course, if you personally want this, I'll add it immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with the auto-rolling behaviour. Let's advertise the change in the release notes and see if people want a switch. I've read users saying they do really like the buffered output a lot, but for linear builds it may be a bit different.
Yeah, that's a valid point. Let me try that. |
2708c12 keeps the DependencyGraph interface independent of Maven. |
80b66e2: adapted your DagWidth implementation |
@@ -29,7 +29,7 @@ public void testRules() { | |||
MavenProject a = newProject("a"), b = newProject("b"), c = newProject("c"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be better to rename the class altogether, given we're testing the SmartProjectDependencyGraph
return Result.success(smartGraph); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I'm a bit skeptic on the benefits of overriding the graph builder to wrap the existing graph by delegating to the standard graph builder, as we have to cast it later to actually access the correct instance.
It may be easier to simply wrap it when needed. If we need to avoid wrapping it multiple times (not sure that's actually the case), we can always cache it in the session / execution context somewhere.
The problem is that it ties us to maven internals (which I'd rather avoid as much as possible) with no real benefits imho.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it ties us to maven internals
That's a valid point
It may be easier to simply wrap it when needed. If we need to avoid wrapping it multiple times (not sure that's actually the case),
Yes, we do. The graph is needed on two locations at least.
we can always cache it in the session / execution context somewhere.
Yeah, storing it somewhere in the session was my first thought. I have not found any general purpose map in the session or in any of its associated classes. Do we have any better option than system properties, ThreadLocal or a static variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MavenSession.getExecutionRequest().getData()
or MavenSession.getRepositorySession().getData()
or MavenSession.getRepositorySession().getCache()
.
Given we want to avoid stale informations, the former may be the better as it won't outlive the current build.
At the moment, it's only used once. I suppose it's used in an additional call to compute the width ?
@ppalaga Wouldn't it be easier to just include the changes on the client (when there's a single thread or theres's only a single project) and defer the server side stuff for 0.3.0 ? |
bd596e2
to
c3ac2f6
Compare
c3ac2f6: DependencyGraph wraps ProjectDependencyGraph and stores it in session.getRequest().getData() If this iteration is not good enough, I do not mind postponing this. |
Ok, let me check asap. |
@ppalaga Could you just add the following change gnodet@b1d9bd5 ? Otherwise looks good ! |
Accepted in 1c5e086 |
Fix #269