private void saveFsState(File dataStorageRoot, BuildFSState state) { final ProjectDescriptor pd = myProjectDescriptor; final File file = new File(dataStorageRoot, FS_STATE_FILE); try { final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); final DataOutputStream out = new DataOutputStream(bytes); try { out.writeInt(FSState.VERSION); out.writeLong(myLastEventOrdinal); boolean hasWorkToDoWithModules = false; for (JpsModule module : pd.getProject().getModules()) { for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) { if (state.hasWorkToDo(new ModuleBuildTarget(module, type))) { hasWorkToDoWithModules = true; break; } } if (hasWorkToDoWithModules) { break; } } out.writeBoolean(hasWorkToDoWithModules); state.save(out); } finally { out.close(); } saveOnDisk(bytes, file); } catch (Throwable e) { LOG.error(e); FileUtil.delete(file); } }
private void runBuild(final MessageHandler msgHandler, CanceledStatus cs) throws Throwable { final File dataStorageRoot = Utils.getDataStorageRoot(myProjectPath); if (dataStorageRoot == null) { msgHandler.processMessage( new CompilerMessage( "build", BuildMessage.Kind.ERROR, "Cannot determine build data storage root for project " + myProjectPath)); return; } if (!dataStorageRoot.exists()) { // invoked the very first time for this project. Force full rebuild myBuildType = BuildType.PROJECT_REBUILD; } final DataInputStream fsStateStream = createFSDataStream(dataStorageRoot); if (fsStateStream != null) { // optimization: check whether we can skip the build final boolean hasWorkToDoWithModules = fsStateStream.readBoolean(); if (myBuildType == BuildType.MAKE && !hasWorkToDoWithModules && scopeContainsModulesOnly(myBuildRunner.getScopes()) && !containsChanges(myInitialFSDelta)) { updateFsStateOnDisk(dataStorageRoot, fsStateStream, myInitialFSDelta.getOrdinal()); return; } } final BuildFSState fsState = new BuildFSState(false); try { final ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState); myProjectDescriptor = pd; if (fsStateStream != null) { try { try { fsState.load(fsStateStream, pd.getModel(), pd.getBuildRootIndex()); applyFSEvent(pd, myInitialFSDelta); } finally { fsStateStream.close(); } } catch (Throwable e) { LOG.error(e); fsState.clearAll(); } } myLastEventOrdinal = myInitialFSDelta != null ? myInitialFSDelta.getOrdinal() : 0L; // free memory myInitialFSDelta = null; // ensure events from controller are processed after FSState initialization myEventsProcessor.startProcessing(); myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler, myBuildType); } finally { saveData(fsState, dataStorageRoot); } }
private void saveData(final BuildFSState fsState, File dataStorageRoot) { final boolean wasInterrupted = Thread.interrupted(); try { saveFsState(dataStorageRoot, fsState); final ProjectDescriptor pd = myProjectDescriptor; if (pd != null) { pd.release(); } } finally { if (wasInterrupted) { Thread.currentThread().interrupt(); } } }
private void applyFSEvent( ProjectDescriptor pd, @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) throws IOException { if (event == null) { return; } final Timestamps timestamps = pd.timestamps.getStorage(); for (String deleted : event.getDeletedPathsList()) { final File file = new File(deleted); Collection<BuildRootDescriptor> descriptor = pd.getBuildRootIndex().findAllParentDescriptors(file, null, null); if (!descriptor.isEmpty()) { if (Utils.IS_TEST_MODE) { LOG.info("Applying deleted path from fs event: " + file.getPath()); } for (BuildRootDescriptor rootDescriptor : descriptor) { pd.fsState.registerDeleted(rootDescriptor.getTarget(), file, timestamps); } } else if (Utils.IS_TEST_MODE) { LOG.info("Skipping deleted path: " + file.getPath()); } } for (String changed : event.getChangedPathsList()) { final File file = new File(changed); Collection<BuildRootDescriptor> descriptors = pd.getBuildRootIndex().findAllParentDescriptors(file, null, null); if (!descriptors.isEmpty()) { if (Utils.IS_TEST_MODE) { LOG.info("Applying dirty path from fs event: " + file.getPath()); } for (BuildRootDescriptor descriptor : descriptors) { pd.fsState.markDirty(null, file, descriptor, timestamps); } } else if (Utils.IS_TEST_MODE) { LOG.info("Skipping dirty path: " + file.getPath()); } } }