mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
- refactor:handle cache corruptions outside IncProjectBuilder
- when forcing rebuild because of cache corruption, keep the original compilation scope
This commit is contained in:
@@ -145,6 +145,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
|
||||
private void runBuild(String projectPath, BuildType buildType, Set<String> modules, Collection<String> artifacts, Map<String, String> builderParams, Collection<String> paths, final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{
|
||||
boolean forceCleanCaches = false;
|
||||
ProjectDescriptor pd;
|
||||
final Project project = loadProject(projectPath);
|
||||
final BuildFSState fsState = new BuildFSState(false);
|
||||
@@ -154,49 +155,70 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
try {
|
||||
timestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, true);
|
||||
if (dataManager.versionDiffers()) {
|
||||
forceCleanCaches = true;
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// second try
|
||||
e.printStackTrace(System.err);
|
||||
LOG.info(e);
|
||||
if (timestamps != null) {
|
||||
timestamps.close();
|
||||
}
|
||||
if (dataManager != null) {
|
||||
dataManager.close();
|
||||
}
|
||||
buildType = BuildType.PROJECT_REBUILD; // force project rebuild
|
||||
forceCleanCaches = true;
|
||||
FileUtil.delete(dataStorageRoot);
|
||||
timestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, true);
|
||||
// second attempt succeded
|
||||
msgHandler.processMessage(new CompilerMessage("compile-server", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage()));
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage()));
|
||||
}
|
||||
|
||||
pd = new ProjectDescriptor(project, fsState, timestamps, dataManager, BuildLoggingManager.DEFAULT);
|
||||
|
||||
try {
|
||||
final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs);
|
||||
if (msgHandler != null) {
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
if (forceCleanCaches && modules.isEmpty() && paths.isEmpty()) {
|
||||
// if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation
|
||||
buildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs);
|
||||
builder.addMessageHandler(msgHandler);
|
||||
}
|
||||
switch (buildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true);
|
||||
break;
|
||||
try {
|
||||
switch (buildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false);
|
||||
break;
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false);
|
||||
break;
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
}
|
||||
break; // break attempts loop
|
||||
}
|
||||
catch (RebuildRequestedException e) {
|
||||
// todo: do not try second attempt here; just notify the calling process about "rebuild requested" and end the session
|
||||
if (attempt == 0) {
|
||||
LOG.info(e);
|
||||
forceCleanCaches = true;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -79,7 +79,7 @@ public class IncProjectBuilder {
|
||||
myMessageHandlers.add(handler);
|
||||
}
|
||||
|
||||
public void build(CompileScope scope, final boolean isMake, final boolean isProjectRebuild) {
|
||||
public void build(CompileScope scope, final boolean isMake, final boolean isProjectRebuild, boolean forceCleanCaches) throws RebuildRequestedException{
|
||||
final LowMemoryWatcher memWatcher = LowMemoryWatcher.register(new Forceable() {
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
@@ -94,47 +94,30 @@ public class IncProjectBuilder {
|
||||
});
|
||||
CompileContext context = null;
|
||||
try {
|
||||
try {
|
||||
if (myProjectDescriptor.dataManager.versionDiffers()) {
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(
|
||||
COMPILE_SERVER_NAME, BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"
|
||||
));
|
||||
context = createContextForForcedRebuild(scope, isMake, isProjectRebuild);
|
||||
}
|
||||
else {
|
||||
context = createContext(scope, isMake, isProjectRebuild);
|
||||
}
|
||||
runBuild(context);
|
||||
}
|
||||
catch (ProjectBuildException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException || cause instanceof IOException) {
|
||||
// force rebuild
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(
|
||||
COMPILE_SERVER_NAME, BuildMessage.Kind.INFO,
|
||||
"Internal caches are corrupted or have outdated format, forcing project rebuild: " +
|
||||
e.getMessage())
|
||||
);
|
||||
flushContext(context);
|
||||
context = createContextForForcedRebuild(scope, isMake, isProjectRebuild);
|
||||
runBuild(context);
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
context = createContext(scope, isMake, isProjectRebuild);
|
||||
runBuild(context, forceCleanCaches);
|
||||
myProjectDescriptor.dataManager.saveVersion();
|
||||
}
|
||||
catch (ProjectBuildException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause == null) {
|
||||
final String msg = e.getMessage();
|
||||
if (!StringUtil.isEmpty(msg)) {
|
||||
myMessageDispatcher.processMessage(new ProgressMessage(msg));
|
||||
}
|
||||
if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException || cause instanceof IOException) {
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(
|
||||
COMPILE_SERVER_NAME, BuildMessage.Kind.INFO,
|
||||
"Internal caches are corrupted or have outdated format, forcing project rebuild: " +
|
||||
e.getMessage())
|
||||
);
|
||||
throw new RebuildRequestedException(cause);
|
||||
}
|
||||
else {
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(COMPILE_SERVER_NAME, cause));
|
||||
if (cause == null) {
|
||||
final String msg = e.getMessage();
|
||||
if (!StringUtil.isEmpty(msg)) {
|
||||
myMessageDispatcher.processMessage(new ProgressMessage(msg));
|
||||
}
|
||||
}
|
||||
else {
|
||||
myMessageDispatcher.processMessage(new CompilerMessage(COMPILE_SERVER_NAME, cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -152,19 +135,6 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private CompileContext createContextForForcedRebuild(CompileScope scope, boolean isMake, boolean isProjectRebuild) throws ProjectBuildException {
|
||||
final CompileContext context;
|
||||
if (isMake || isProjectRebuild) {
|
||||
context = createContext(new AllProjectScope(scope.getProject(), scope.getArtifacts(), true), false, true);
|
||||
}
|
||||
else {
|
||||
//in case of forced compilation keep the scope, but remove all caches
|
||||
context = createContext(scope, false, false);
|
||||
cleanOutputRoots(context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private static void flushContext(CompileContext context) {
|
||||
if (context != null) {
|
||||
context.getTimestampStorage().force();
|
||||
@@ -206,12 +176,12 @@ public class IncProjectBuilder {
|
||||
return myModulesProcessed / myTotalModulesWork;
|
||||
}
|
||||
|
||||
private void runBuild(CompileContext context) throws ProjectBuildException {
|
||||
private void runBuild(CompileContext context, boolean forceCleanCaches) throws ProjectBuildException {
|
||||
context.setDone(0.0f);
|
||||
|
||||
LOG.info("Building project '" + context.getProject().getProjectName() + "'; isRebuild:" +context.isProjectRebuild() + "; isMake:" + context.isMake());
|
||||
|
||||
if (context.isProjectRebuild()) {
|
||||
if (context.isProjectRebuild() || forceCleanCaches) {
|
||||
cleanOutputRoots(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.jetbrains.jps.incremental;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 9/20/11
|
||||
*/
|
||||
public class RebuildRequestedException extends ProjectBuildException{
|
||||
|
||||
public RebuildRequestedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class ServerState {
|
||||
public void startBuild(String projectPath, BuildType buildType, Set<String> modules, Collection<String> artifacts,
|
||||
Map<String, String> builderParams, Collection<String> paths, final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{
|
||||
|
||||
|
||||
boolean forceCleanCaches = false;
|
||||
ProjectDescriptor pd;
|
||||
synchronized (myConfigurationLock) {
|
||||
pd = myProjects.get(projectPath);
|
||||
@@ -143,17 +143,21 @@ class ServerState {
|
||||
try {
|
||||
timestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, myKeepTempCachesInMemory);
|
||||
if (dataManager.versionDiffers()) {
|
||||
forceCleanCaches = true;
|
||||
msgHandler.processMessage(new CompilerMessage("compile-server", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// second try
|
||||
e.printStackTrace(System.err);
|
||||
LOG.info(e);
|
||||
if (timestamps != null) {
|
||||
timestamps.close();
|
||||
}
|
||||
if (dataManager != null) {
|
||||
dataManager.close();
|
||||
}
|
||||
buildType = BuildType.PROJECT_REBUILD; // force project rebuild
|
||||
forceCleanCaches = true;
|
||||
FileUtil.delete(dataStorageRoot);
|
||||
timestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, myKeepTempCachesInMemory);
|
||||
@@ -168,28 +172,44 @@ class ServerState {
|
||||
}
|
||||
|
||||
try {
|
||||
final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs);
|
||||
if (msgHandler != null) {
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
if (forceCleanCaches && modules.isEmpty() && paths.isEmpty()) {
|
||||
// if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation
|
||||
buildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs);
|
||||
builder.addMessageHandler(msgHandler);
|
||||
}
|
||||
switch (buildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true);
|
||||
break;
|
||||
try {
|
||||
switch (buildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false);
|
||||
break;
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false);
|
||||
break;
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
}
|
||||
break; // break attempts loop
|
||||
}
|
||||
catch (RebuildRequestedException e) {
|
||||
if (attempt == 0) {
|
||||
LOG.info(e);
|
||||
forceCleanCaches = true;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -210,7 +210,7 @@ public abstract class IncrementalTestCase extends TestCase {
|
||||
new IncProjectBuilder(
|
||||
projectDescriptor, BuilderRegistry.getInstance(), Collections.<String, String>emptyMap(), CanceledStatus.NULL
|
||||
).build(
|
||||
new AllProjectScope(project, Collections.<Artifact>emptySet(), true), false, true
|
||||
new AllProjectScope(project, Collections.<Artifact>emptySet(), true), false, true, false
|
||||
);
|
||||
|
||||
modify();
|
||||
@@ -222,7 +222,7 @@ public abstract class IncrementalTestCase extends TestCase {
|
||||
new IncProjectBuilder(
|
||||
projectDescriptor, BuilderRegistry.getInstance(), Collections.<String, String>emptyMap(), CanceledStatus.NULL
|
||||
).build(
|
||||
new AllProjectScope(project, Collections.<Artifact>emptySet(), false), true, false
|
||||
new AllProjectScope(project, Collections.<Artifact>emptySet(), false), true, false, false
|
||||
);
|
||||
|
||||
final String expected = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(getBaseDir() + ".log")));
|
||||
|
||||
+6
-1
@@ -195,7 +195,12 @@ public abstract class ArtifactBuilderTestCase extends UsefulTestCase {
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.build(new AllProjectScope(myDescriptor.project, new HashSet<Artifact>(Arrays.asList(artifacts)), force), !force, false);
|
||||
try {
|
||||
builder.build(new AllProjectScope(myDescriptor.project, new HashSet<Artifact>(Arrays.asList(artifacts)), force), !force, false, false);
|
||||
}
|
||||
catch (RebuildRequestedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
if (shouldFail) {
|
||||
assertFalse("Build not failed as expected", errorMessages.isEmpty());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user