Community
Participate
Working Groups
1. Turn on autobuild 2. Take a moderately-sided workspace (something that will take at least 30 sec to compile) 3. "Clean..." the workspace 4. While the build is running, save a file. You will get a "User Operation is Waiting" dialog until the build finishes. The user can safely cancel the "Building Workspace" job and proceed with their work since saving the file will trigger another autobuild which will end up taking into account the saved file plus everything that the cancelled build would have done. It should not be necessary for users to figure this out, see the dialog, or to manually cancel the build. Basically, any job that was triggered as the result of an autobuild should be flagged. If another job arrives that needs write access to the workspace any running autobuild jobs should be cancelled and restarted once the new job finishes. This is most noticiable when the UI is waiting for NEWJOB, but it also applies when both jobs are background jobs. For example, imagine that the user requests a "clean..." on all projects and a few moments later starts a background job that will end up replacing the entire contents of the workspace. There would be no point continuing with the autobuild triggered by the "clean..." since its output will be rendered redundant once the replace job runs.
Not sure exactly who to file this against, since it clearly spans components.
Autobuild can currently be either "interrupted", or "cancelled". A build is interrupted automatically when, as you mention, another thread is waiting to modify the workspace while the build is running. Individual builders, such as the Java builder, do not currently respond to builder interruption. The platform core build infrastructure checks for an interrupt after each individual builder has finished running. The result is that interrupting a build is not nearly as responsive as cancelling a build. The reason for having this distinction is that cancellation typically results in builder work being lost. Essentially, cancellation of an incremental build and gracefully recovering on the next build is too complicated - the Java builder simply throws away all its build state on cancellation, and the next build will be a full build. This is typically not a good thing from the user's point of view, and results in the subsequent build being very expensive. This is why we don't cancel builds "for free" when another thread is waiting. In your particular case, since you're doing a full build anyway, there is no harm in cancelling the builder. The short summary is that the builder infrastructure is tuned for the incremental build case - the clean and full rebuild of your workspace is generally never required. We sometimes use it because of various bugs in the integration builds, but essentially clean and full build only used as a workaround for other bugs. I am curious to know if you hit these long pauses waiting for the builder in incremental build cases? If we decided this case was worth optimizing, the Java builder could be changed to respond to interruption more quickly during a full build (since there is no incremental build state to lose), by checking the flag IncrementalProjectBuilder.isInterrupted().
I don't often do a funll rebuild. I just used that as an example since it's easy to reproduce. I seem to hit this frequently even with incremental builds. My workspace isn't in a good enough state to try testing right now, but I seem to recall observing it in the following situations: 1. Perform several project-wide operations at once. For example, replace the first project from head, delete the second project, and update the third project from CVS. Each operation triggers a build and waits on the previous one. 2. I save a java file during an autobuild (or CVS replace... or update from CVS... etc. etc.) 3. I have a bunch of dirty editors. I save them one-at-a-time, the first one triggers an autobuild, and I end up waiting before being able to save the rest. 4. I have an editor open. I save it, triggering an autobuild. Then I notice a typo in what I just saved, correct the typo, re-save, and end up with the UI thread waiting on the builder.
In 3.3 build, when such operation is triggered, you get the choice of cancelling the running build. Closing as WORKSFORME.
> Closing as WORKSFORME. I disagree. Every time I switch to a new integration build, autobuild basically rebuilds the whole workspace. During this time, my workbench is almost unusable, since most operations (like quick fixes or saving a file) raise a "User Operation is Waiting" dialog, where I have to find the build job and cancel it manually (often more than once). This is also a problem when you select a big number of incoming changes in the Synchronize view, choose to Update them, and then try to update another incoming change.
The problem is that it is not clear to the end user which jobs can be canceled without causing problems later on. Ideally, if the Java builder is blocking a UI operation, it should just go away automatically without even showing the dialog, because we know that the build will continue after the UI operation. The system should do this for the user rather than the user having to learn about jobs, how to cancel them, and how to tell which jobs are safe to cancel.
I agree with John that only the full build case is worth optimizing from the Java builder standpoint. Interrupting an incremental build would force us to start a full build next time the Java builder is invoked. John, if we checked IncrementalProjectBuilder.isInterrupted() during a full build, when would the Java builder get the next full build request ? I'm thinking of the autobuild case that usually guaranties that the workspace is entirely built. If we abort the full build while the user operation is running, do we get a full build request once the user operation has finished ?
Further to Markus' and Boris' comments (5 and 6), the whole point to me of jobs is to ensure that the UI remains responsive to the user while long background operations like builds are happening. That however is not the experience we are providing as outlined in this bug. For products like WID the tendency is to revert to turning off autobuild and doing manual builds so that you (the user) can regain control over when you can actually use the UI (and when you should go get a coffee). So our whole story is kind of failing in practice. Note the WID problem involves the JDT builder but many others as well.
(In reply to comment #7) >... Interrupting an incremental build would force us to > start a full build next time the Java builder is invoked. Just curious - why is this the case? Does it force a full build for the entire workspace, or the particular project that was being built at the time it was interrupted?
Jerome, regarding comment #7: the recommended pattern if you interrupt is to call IncrementalProjectBuilder.forgetLastBuiltState() before returning. This ensures that the next invocation of that builder on that project will be a full build (because this method causes us to throw away the pointer to the old tree state, so computing a delta is impossible). Some general comments: Since this bug is a couple of years old, I should point out that there were some bugs in past releases that caused autobuild interruption to not work properly. The most recent was bug 170356 in 3.2.2 and early 3.3 milestones. For what it's worth, the interruption behaviour now is much better than it was in the past. For the Java builder case, I think optimizing only the full build case is a reasonable thing to try. Incremental Java builds are rarely very long - it's likely that most cases where people notice a delay is due to a full build. I also wanted to point out that build isn't the root cause of the problem here. Autobuild is always happening outside the UI thread. The root cause of the UI being blocked is people attempt to perform long-running work (obtain locks) in the UI thread.
(In reply to comment #10) > I also wanted to point out that build isn't the root cause of the problem here. > Autobuild is always happening outside the UI thread. The root cause of the UI > being blocked is people attempt to perform long-running work (obtain locks) in > the UI thread. A common scenario is when you try to save an editor while the build is running, the "operation is blocked" dialog is coming up. So yes, someone else is obtaining a lock in the UI thread, but for a good reason. Overall, the user experience would be better if we had a way to automatically cancel and/or pause the build in this case, letting the user operation proceed, and then resuming the build.
> Overall, the user experience would be better if we had a way to automatically > cancel and/or pause the build in this case, letting the user operation proceed, > and then resuming the build. Yes, absolutely agreed, this would be better. However, incremental build is quite a complicated algorithm - it is very difficult to stop at a random point in the middle and resume exactly where it left off. There is a trade-off between responsiveness and efficiency here. It could cancel immediately, and then do a full build later. This could make a build that would take one second end up taking over a minute.
(In reply to comment #10) > Jerome, regarding comment #7: the recommended pattern if you interrupt is to > call IncrementalProjectBuilder.forgetLastBuiltState() before returning. This > ensures that the next invocation of that builder on that project will be a full > build (because this method causes us to throw away the pointer to the old tree > state, so computing a delta is impossible). Thanks John. The question is however: when does the "next invocation of that builder" occurs ? In auto-build mode, we cannot expect the user to force a build to trigger the invocation of the builder. If this invocation doesn't occur automatically, then I don't think interrupting a full build is a good idea either.
>In auto-build mode, we cannot expect the user to force a > build to trigger the invocation of the builder. If this invocation doesn't > occur automatically, then I don't think interrupting a full build is a good > idea either. I agree. When the autobuild job auto-interrupts, it also auto-resumes ;) You can assume when autobuild is on, the resources plugin will take responsibility for making sure everything's in a built state at the earliest opportunity. The autobuild job reschedules itself immediately when interrupted. This puts it back in the job queue, and it will run as soon as the operation that interrupted it completes.
Thanks John. Kent, I think we should consider honoring IncrementalProjectBuilder.isInterrupted() during a full build by calling IncrementalProjectBuilder.forgetLastBuiltState().
*** Bug 202442 has been marked as a duplicate of this bug. ***
Created attachment 77915 [details] Proposed patch
Released patch into HEAD for 3.4M2 Verified by ensuring that only full builds are restarted when a small change is made to a source file AND that incremental builds are not restarted when the same change is made.
Caused problems for some users - removed for now.
Because of the problems found with some misbehaving plugins, we cannot rely on the interrupted flag. Removed patch from HEAD See bug 203058
(In reply to comment #20) > Because of the problems found with some misbehaving plugins, we cannot rely on > the interrupted flag. > > Removed patch from HEAD > > See bug 203058 > Mmm, I don't understand that: In AutoBuildJob.interrupt() it says: 'Another thread is attempting to modify the workspace. Flag the auto-build as interrupted...' Can't the code in Workspace.prepareOperation: if (rule != null) buildManager.interrupt(); be safely replaced by something like if (rule != null && ResourcesPlugin.getWorkspace().getRoot().isConflicting(rule)) buildManager.interrupt(); The rule leading to Bug 203058 is called 'NonLockingRule' I therefore guess that it will not conflict with the workspace rule...
Benno, you may be right that we can optimize the interrupt behaviour a bit. Can you enter a separate bug against Platform Resources for that? It's really separate from this bug about increasing responsiveness to interrupts.
Verified for 3.4M2
(In reply to comment #20) > Because of the problems found with some misbehaving plugins, we cannot rely on > the interrupted flag. Sorry, but this cannot be the end of the story. We have identified a scenario where we agree that builds are not interrupted as timely as they should, and we have a proper fix for it, but we don't release the fix, because it *could* cause problems with misbehaving third-party builders (it probably won't after bug 203410, see comment 21). IMO, JDT/Core should re-release the fix now, since it is just using a non-deprecated API in the suggested way. If the Platform/Resources team thinks that the platform should prevent the problem from bug 203058, then either IncrementalProjectBuilder.isInterrupted() should be publicly marked as broken/deprecated, or the builder should try to detect such endless loop scenarios where a builder is cancelling itself multiple times when interrupted.
Actually I'll disagree on several points: 1. "That the fix is good" I used the fix for over a week and didn't like it. We need a threshold that controls when a full build should be cancelled and then restarted with the new change included. As a user I would rather wait 40 seconds for the full build (its already been running for 20 seconds) to finish then 0.5 seconds for the incremental build to run, then stop the full build & wait 1 minute for it run completely again. 2. "it *could* cause problems with misbehaving third-party builders" 'Could' is more than enough reason to not release the fix. 3. Until the platform has a solution for repeated offenders, then we do not have an acceptable solution to the problem.
> We need a threshold that controls when a full build should be cancelled [..] Sounds good to me. > 3. Until the platform has a solution for repeated offenders, then we do not > have an acceptable solution to the problem. I disagree here. Eclipse is an open platform, and therefore, there's always room for misbehaving third-party plug-ins that can impede the functioning of the platform. I filed bug 206637 for better detection of this case in the platform. However, I don't think the existence of one misbehaving plug-in should prevent JDT/Core from making progress by using an API the way it's intended to be used.
>I don't think the existence of one misbehaving plug-in should prevent JDT/Core I do. If a single user cannot build their workspace, then this fix is insufficient & cannot be released. We need the platform to detect repeat offenders & ignore them during future builds.
Was there any progress on platform side ? If not, I think Kent is right that we cannot be right alone and break the world.
> Was there any progress on platform side ? Yes, bug 203410 has been fixed (10 days after it had been filed), so we currently don't have a single scenario that would have a problem.
I think we should wait to see the impact of bug 198591 There are better solutions to improve the 'feel' of editing a file during a build than killing the build & restarting it. If builds do not need workspace locks or do not need them for very long then saving a file should succeed sooner & possibly soon enough when compared to the alternative of killing a build.
Created attachment 189612 [details] Shows a "User is waiting" dialog, waiting for a job that won't terminate and forbids to save the document.
Version: Helios Release Build id: 20100617-1415 The problem is still there and it is quite annoying when work gets lost because it cannot be saved. There should be an option to force eclipse to save the document without taking care of running jobs. If a file is saved, a running build could continue and the saved document can be marked "dirty" for compiling. After the build run finished, the saved document and any other which have dependencies could be recompiled in a second run. The user should always be able to save or modify any files. If eclipse gets idle then it could start to recompile the modified files and depending others as if they were just saved in that time.
(In reply to comment #32) > Version: Helios Release > Build id: 20100617-1415 > > The problem is still there and it is quite annoying when work gets lost > because it cannot be saved. I agree, however, as you can see the offending builder is the Maven builder. I suggest you report your bug there.
I used to wait for the "User Operating is Waiting" dialog to go away on its own, but I recently realized that that in my version of eclipse (latest) I can just close the dialog and keep editing files. This dialog is only modal until you close it. Closing it does not stop the queued actions from happening in the background while you continue working!