support progress for jps-based compilation

This commit is contained in:
Eugene Zhuravlev
2012-01-13 20:21:58 +01:00
parent 46a1d47c02
commit f4a955ea53
10 changed files with 140 additions and 12 deletions
@@ -426,14 +426,17 @@ public class CompileDriver {
moduleNames.add(module.getName());
}
}
compileContext.getProgressIndicator().setIndeterminate(true); // todo
return JpsServerManager.getInstance().submitCompilationTask(myProject.getLocation(), moduleNames, !isMake, new JpsServerResponseHandlerAdapter() {
public void handleCompileMessage(JpsRemoteProto.Message.Response.CompileMessage compilerMessage) {
final JpsRemoteProto.Message.Response.CompileMessage.Kind kind = compilerMessage.getKind();
//System.out.println(compilerMessage.getText());
if (kind == JpsRemoteProto.Message.Response.CompileMessage.Kind.PROGRESS) {
compileContext.getProgressIndicator().setText(compilerMessage.getText());
final ProgressIndicator indicator = compileContext.getProgressIndicator();
indicator.setText(compilerMessage.getText());
if (compilerMessage.hasDone()) {
indicator.setFraction(compilerMessage.getDone());
}
}
else {
final CompilerMessageCategory category = kind == JpsRemoteProto.Message.Response.CompileMessage.Kind.ERROR ? CompilerMessageCategory.ERROR
@@ -119,6 +119,7 @@ message Message {
optional uint64 problem_location_offset = 6;
optional uint64 line = 7;
optional uint64 column = 8;
optional float done = 9;
}
required Type response_type = 1;
@@ -4346,6 +4346,13 @@ public final class JpsRemoteProto {
public boolean hasColumn() { return hasColumn; }
public long getColumn() { return column_; }
// optional float done = 9;
public static final int DONE_FIELD_NUMBER = 9;
private boolean hasDone;
private float done_ = 0F;
public boolean hasDone() { return hasDone; }
public float getDone() { return done_; }
private void initFields() {
kind_ = org.jetbrains.jps.api.JpsRemoteProto.Message.Response.CompileMessage.Kind.ERROR;
}
@@ -4381,6 +4388,9 @@ public final class JpsRemoteProto {
if (hasColumn()) {
output.writeUInt64(8, getColumn());
}
if (hasDone()) {
output.writeFloat(9, getDone());
}
}
private int memoizedSerializedSize = -1;
@@ -4421,6 +4431,10 @@ public final class JpsRemoteProto {
size += com.google.protobuf.CodedOutputStream
.computeUInt64Size(8, getColumn());
}
if (hasDone()) {
size += com.google.protobuf.CodedOutputStream
.computeFloatSize(9, getDone());
}
memoizedSerializedSize = size;
return size;
}
@@ -4589,6 +4603,9 @@ public final class JpsRemoteProto {
if (other.hasColumn()) {
setColumn(other.getColumn());
}
if (other.hasDone()) {
setDone(other.getDone());
}
return this;
}
@@ -4643,6 +4660,10 @@ public final class JpsRemoteProto {
setColumn(input.readUInt64());
break;
}
case 77: {
setDone(input.readFloat());
break;
}
}
}
}
@@ -4801,6 +4822,24 @@ public final class JpsRemoteProto {
return this;
}
// optional float done = 9;
public boolean hasDone() {
return result.hasDone();
}
public float getDone() {
return result.getDone();
}
public Builder setDone(float value) {
result.hasDone = true;
result.done_ = value;
return this;
}
public Builder clearDone() {
result.hasDone = false;
result.done_ = 0F;
return this;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.jpsservice.Message.Response.CompileMessage)
}
@@ -132,11 +132,11 @@ public class ProtoUtil {
}
public static JpsRemoteProto.Message.Response createCompileInfoMessageResponse(String text, String path) {
return createCompileMessageResponse(BuildMessage.Kind.PROGRESS, text, path, -1L, -1L, -1L, -1, -1);
return createCompileMessageResponse(BuildMessage.Kind.PROGRESS, text, path, -1L, -1L, -1L, -1, -1, -1.0f);
}
public static JpsRemoteProto.Message.Response createCompileProgressMessageResponse(String text) {
return createCompileMessageResponse(BuildMessage.Kind.PROGRESS, text, null, -1L, -1L, -1L, -1, -1);
public static JpsRemoteProto.Message.Response createCompileProgressMessageResponse(String text, float done) {
return createCompileMessageResponse(BuildMessage.Kind.PROGRESS, text, null, -1L, -1L, -1L, -1, -1, done);
}
public static JpsRemoteProto.Message.Response createCompileErrorMessageResponse(String text, String path,
@@ -145,14 +145,14 @@ public class ProtoUtil {
long offset,
long line,
long column) {
return createCompileMessageResponse(CompilerMessage.Kind.ERROR, text, path, beginOffset, endOffset, offset, line, column);
return createCompileMessageResponse(CompilerMessage.Kind.ERROR, text, path, beginOffset, endOffset, offset, line, column, -1.0f);
}
public static JpsRemoteProto.Message.Response createCompileMessageResponse(final BuildMessage.Kind kind,
String text,
String path,
long beginOffset, long endOffset, long offset, long line,
long column) {
long column, float done) {
final JpsRemoteProto.Message.Response.CompileMessage.Builder builder = JpsRemoteProto.Message.Response.CompileMessage.newBuilder();
switch (kind) {
@@ -189,6 +189,9 @@ public class ProtoUtil {
if (column > 0L) {
builder.setColumn(column);
}
if (done >= 0.0f) {
builder.setDone(done);
}
return JpsRemoteProto.Message.Response.newBuilder().setResponseType(JpsRemoteProto.Message.Response.Type.COMPILE_MESSAGE).setCompileMessage(builder.build()).build();
}
@@ -44,6 +44,14 @@ public class BuilderRegistry {
}
public int getTotalBuilderCount() {
int count = 0;
for (BuilderCategory category : BuilderCategory.values()) {
count += getBuilders(category).size();
}
return count;
}
public List<BuildTask> getBeforeTasks(){
return Collections.emptyList(); // todo
}
@@ -53,7 +61,7 @@ public class BuilderRegistry {
}
public List<Builder> getBuilders(BuilderCategory category){
return myBuilders.get(category); // todo
return Collections.unmodifiableList(myBuilders.get(category)); // todo
}
public void shutdown() {
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.ether.dependencyView.Mappings;
import org.jetbrains.jps.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
import org.jetbrains.jps.incremental.storage.TimestampStorage;
@@ -33,6 +34,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
private volatile boolean myErrorsFound = false;
private final long myCompilationStartStamp;
private final TimestampStorage myTsStorage;
private float myDone = -1.0f;
public CompileContext(String projectName, CompileScope scope,
boolean isMake,
@@ -158,6 +160,9 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
if (msg.getKind() == BuildMessage.Kind.ERROR) {
myErrorsFound = true;
}
if (msg instanceof ProgressMessage) {
((ProgressMessage)msg).setDone(myDone);
}
myDelegateMessageHandler.processMessage(msg);
}
@@ -213,6 +218,15 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
return myRootsIndex.getModuleRoots(module);
}
public int getTotalModuleCount() {
return myRootsIndex.getTotalModuleCount();
}
public void setDone(float done) {
myDone = done;
processMessage(new ProgressMessage("", done));
}
private static enum DirtyMarkScope{
PRODUCTION, TESTS, BOTH
}
@@ -36,11 +36,17 @@ public class IncProjectBuilder {
}
};
private float myModulesProcessed = 0.0f;
private final float myTotalModulesWork;
private final int myTotalBuilderCount;
public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry) {
myProjectDescriptor = pd;
myBuilderRegistry = builderRegistry;
myProductionChunks = new ProjectChunks(pd.project, ClasspathKind.PRODUCTION_COMPILE);
myTestChunks = new ProjectChunks(pd.project, ClasspathKind.TEST_COMPILE);
myTotalModulesWork = (float) pd.rootsIndex.getTotalModuleCount() * 2; /* multiply by 2 to reflect production and test sources */
myTotalBuilderCount = builderRegistry.getTotalBuilderCount();
}
public void addMessageHandler(MessageHandler handler) {
@@ -97,7 +103,14 @@ public class IncProjectBuilder {
}
}
private float updateFractionBuilderFinished(final float delta) {
myModulesProcessed += delta;
return myModulesProcessed / myTotalModulesWork;
}
private void runBuild(CompileContext context) throws ProjectBuildException {
context.setDone(0.0f);
if (context.isProjectRebuild()) {
cleanOutputRoots(context);
}
@@ -198,6 +211,10 @@ public class IncProjectBuilder {
if (scope.isAffected(chunk)) {
buildChunk(context, chunk);
}
else {
final float fraction = updateFractionBuilderFinished(chunk.getModules().size());
context.setDone(fraction);
}
}
}
@@ -279,18 +296,34 @@ public class IncProjectBuilder {
if (builders.isEmpty()) {
return;
}
float stageCount = myTotalBuilderCount;
int stagesPassed = 0;
final int modulesInChunk = chunk.getModules().size();
boolean nextPassRequired;
do {
nextPassRequired = false;
context.beforeNextCompileRound(chunk);
for (Builder builder : builders) {
final Builder.ExitCode buildResult = builder.build(context, chunk);
if (buildResult == Builder.ExitCode.ABORT) {
throw new ProjectBuildException("Builder " + builder.getDescription() + " requested build stop");
}
if (buildResult == Builder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
if (!nextPassRequired) {
// recalculate basis
myModulesProcessed -= (stagesPassed * modulesInChunk) / stageCount;
stageCount += myTotalBuilderCount;
myModulesProcessed += (stagesPassed * modulesInChunk) / stageCount;
}
nextPassRequired = true;
}
stagesPassed++;
final float fraction = updateFractionBuilderFinished(modulesInChunk / (stageCount));
context.setDone(fraction);
}
}
while (nextPassRequired);
@@ -16,9 +16,12 @@ import java.util.*;
public class ModuleRootsIndex {
private final Map<File, RootDescriptor> myRootToModuleMap = new HashMap<File, RootDescriptor>();
private final Map<Module, List<RootDescriptor>> myModuleToRootsMap = new HashMap<Module, List<RootDescriptor>>();
private final int myTotalModuleCount;
public ModuleRootsIndex(Project project) {
for (Module module : project.getModules().values()) {
final Collection<Module> allModules = project.getModules().values();
myTotalModuleCount = allModules.size();
for (Module module : allModules) {
List<RootDescriptor> moduleRoots = myModuleToRootsMap.get(module);
if (moduleRoots == null) {
moduleRoots = new ArrayList<RootDescriptor>();
@@ -39,6 +42,10 @@ public class ModuleRootsIndex {
}
}
public int getTotalModuleCount() {
return myTotalModuleCount;
}
@NotNull
public List<RootDescriptor> getModuleRoots(Module module) {
final List<RootDescriptor> descriptors = myModuleToRootsMap.get(module);
@@ -5,7 +5,22 @@ package org.jetbrains.jps.incremental.messages;
* Date: 9/29/11
*/
public class ProgressMessage extends BuildMessage {
private volatile float myDone;
public ProgressMessage(String messageText) {
this(messageText, -1.0f);
}
public ProgressMessage(String messageText, float done) {
super(messageText, Kind.PROGRESS);
myDone = done;
}
public float getDone() {
return myDone;
}
public void setDone(float done) {
myDone = done;
}
}
@@ -7,6 +7,7 @@ import org.jetbrains.jps.api.*;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -192,11 +193,15 @@ class ServerMessageHandler extends SimpleChannelHandler {
response = ProtoUtil.createCompileMessageResponse(
compilerMessage.getKind(), text, compilerMessage.getSourcePath(),
compilerMessage.getProblemBeginOffset(), compilerMessage.getProblemEndOffset(),
compilerMessage.getProblemLocationOffset(), compilerMessage.getLine(), compilerMessage.getColumn()
);
compilerMessage.getProblemLocationOffset(), compilerMessage.getLine(), compilerMessage.getColumn(),
-1.0f);
}
else {
response = ProtoUtil.createCompileProgressMessageResponse(buildMessage.getMessageText());
float done = -1.0f;
if (buildMessage instanceof ProgressMessage) {
done = ((ProgressMessage)buildMessage).getDone();
}
response = ProtoUtil.createCompileProgressMessageResponse(buildMessage.getMessageText(), done);
}
Channels.write(myChannelContext.getChannel(), ProtoUtil.toMessage(mySessionId, response));
}