Bug 173944 - cannot cancel build
Summary: cannot cancel build
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.3 RC1   Edit
Assignee: Kent Johnson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-12 17:58 EST by Adam Kiezun CLA
Modified: 2007-05-15 10:05 EDT (History)
2 users (show)

See Also:
jerome_lanneluc: review+


Attachments
Proposed patch (2.57 KB, patch)
2007-05-08 13:53 EDT, Kent Johnson CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Kiezun CLA 2007-02-12 17:58:04 EST
3.2.1
I have a (generated) Java file of more than 18GB. After I pressed 'refresh' (autobuild on), the IDE froze for 10 minutes, pressing cancel did not help and I had to kill the process. 
'Cancel' should always immediately stop the current activity and restore IDE's responsiveness.
Comment 1 Philipe Mulet CLA 2007-02-13 04:38:47 EST
In theory yes, but your scenario is a degenerated one. The Java builder will check for cancel after each file being compiled, which generally is good enough. Your scenario is far from the standard cases we see.
Comment 2 Adam Kiezun CLA 2007-02-13 08:02:51 EST
oops, by '18GB' I meant '18MB'

Generated files of this size are probably not unheard of in business settings, with EJBs, model-based generated code etc.
Comment 3 Markus Keller CLA 2007-04-27 04:50:24 EDT
This is also a problem with smaller files. I often want to kill an autobuild job that blocks other operations, and I have to wait for 10+ seconds until the build really cancels (in my dev workspace).
Comment 4 Jerome Lanneluc CLA 2007-04-27 04:56:34 EDT
Markus, can you please attach Thread Dumps so that we know what code is running (and not checking for isCancelled()) in your case ?
Comment 5 Markus Keller CLA 2007-04-27 13:24:44 EDT
Steps in I20070427-0010:
- check out org.eclipse.jdt.ui
- Project > Clean all
- when build starts, send to background
- open a .java editor, add some whitespace, save
- cancel the blocking build job (shouldn't we cancel autobuild automatically?)
=> need to wait here for several seconds:

"Worker-6" prio=6 tid=0x05f0c000 nid=0x2614 runnable [0x0799f000..0x0799fc14]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(FileInputStream.java:199)
        at org.eclipse.core.internal.resources.ContentDescriptionManager$LazyFileInputStream.read(ContentDescriptionManager.java:167)
        at java.io.InputStream.read(InputStream.java:85)
        at org.eclipse.core.internal.content.LazyInputStream.loadBlock(LazyInputStream.java:99)
        at org.eclipse.core.internal.content.LazyInputStream.ensureAvailable(LazyInputStream.java:64)
        at org.eclipse.core.internal.content.LazyInputStream.read(LazyInputStream.java:119)
        at org.eclipse.core.internal.content.TextContentDescriber.getByteOrderMark(TextContentDescriber.java:65)
        at org.eclipse.core.internal.content.TextContentDescriber.describe(TextContentDescriber.java:49)
        at org.eclipse.core.internal.content.ContentType.describe(ContentType.java:161)
        at org.eclipse.core.internal.content.ContentType.internalGetDescriptionFor(ContentType.java:458)
        at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:314)
        at org.eclipse.core.internal.content.ContentTypeCatalog.getDescriptionFor(ContentTypeCatalog.java:318)
        at org.eclipse.core.internal.content.ContentTypeMatcher.getDescriptionFor(ContentTypeMatcher.java:86)
        at org.eclipse.core.internal.resources.ContentDescriptionManager.readDescription(ContentDescriptionManager.java:400)
        at org.eclipse.core.internal.resources.ContentDescriptionManager.getDescriptionFor(ContentDescriptionManager.java:339)
        - locked <0x12cd3ab8> (a org.eclipse.core.internal.resources.ContentDescriptionManager)
        at org.eclipse.core.internal.resources.File.internalGetCharset(File.java:250)
        at org.eclipse.core.internal.resources.File.getCharset(File.java:211)
        at org.eclipse.core.internal.resources.File.getCharset(File.java:198)
        at org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray(Util.java:1029)
        at org.eclipse.jdt.internal.core.builder.SourceFile.getContents(SourceFile.java:79)
        at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:9219)
        at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:9191)
        at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:7847)
        at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:587)
        at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:357)
        at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:371)
        at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:356)
        at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:173)
        at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:293)
        at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:59)
        at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:269)
        at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:177)
        at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:624)
        at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
        at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:166)
        at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:197)
        at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:246)
        at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
        at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:249)
        at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:302)
        at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:334)
        at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:137)
        at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235)
        at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Comment 6 Jerome Lanneluc CLA 2007-05-02 04:32:56 EDT
Unfortunately we are in the compiler layer (Compiler.beginToCompile()) that knows nothing about progress monitors.

Kent, do you think it would be possible to add a hook in beginToCompile() so that the compiler requestor as a chance to check if its progress monitor is canceled ?
Comment 7 Kent Johnson CLA 2007-05-03 15:58:21 EDT
We checked notifier.checkCancel(); on line 353 of AbstractImageBuilder.compile (plus several points before) and will check again when the first source file is finished compiling.

So you have to hit a pretty small window during a full build after line 353 & before the first file is finished compiling to have to wait a few seconds (unless of course you're compiling a massive source file).

Checking for cancel is a polling issue - how much time is an acceptable delay after cancel is hit vs. how much slower is a build if we check after every line of code?

I'm not convinced we should create a new compiler/requestor API that attachs a notifier to the compiler so it can check also.

We're checking several times in the builder before the compiler is called & after every file is finished compiling. Only full builds (or massive source files) when cancel is pressed during a specific window, will cause any noticeable delay in it taking affect.
Comment 8 Adam Kiezun CLA 2007-05-03 16:10:12 EDT
sounds more like WONTFIX than WORKSFORME because the original problem is not solved
Comment 9 Jerome Lanneluc CLA 2007-05-04 04:35:46 EDT
I instrumented beginToCompile() to show the time this method takes and I followed steps from comment 5. beginToCompile() took around 7s. I don't think it is acceptable to press the Cancel button and wait for 7s before the build is canceled.
Comment 10 Kent Johnson CLA 2007-05-04 10:15:05 EDT
But Jerome you didn't press cancel until AFTER we had checked the cancel button several times while removing all .class files, copying any extra resources, computing which source files to compile & called the compiler.

As long as cancel is detected by polling, there will be times when you have to wait for it to take affect.

So yes this is a WONTFIX - change the notifier to send an AbortOperation exception.

We could easily listen for that and abort instantly, but don't expect polling react immediately.
Comment 11 Kent Johnson CLA 2007-05-08 13:52:20 EDT
After discussing with Jerome, we've decided to add an additional check for cancel inside the NameEnvironment when searching for a type.

We still cannot promise immediate reaction to the cancel button but this should reduce the wait time to an acceptable amount with normal projects.
Comment 12 Kent Johnson CLA 2007-05-08 13:53:57 EDT
Created attachment 66332 [details]
Proposed patch
Comment 13 Kent Johnson CLA 2007-05-09 10:21:26 EDT
Released into HEAD for 3.3RC1.
Comment 14 David Audel CLA 2007-05-15 10:05:21 EDT
Verified for 3.3RC1 using I20070515-0010