DefaultResourceDescriptionManager.isAffected inconsistency when AutoBuild is cancelled [message #1785963] |
Mon, 23 April 2018 15:09 |
Sergio Otero Messages: 39 Registered: June 2012 |
Member |
|
|
Hi
I've been having inconsistencies in the output that generates my grammar and i've finally been able to reproduce it in a small project and find the root cause.
Let's suppose this dummy grammar
grammar org.xtext.example.mydsl.AutoBuildCancel with org.eclipse.xtext.common.Terminals
generate autoBuildCancel "http://www.xtext.org/example/mydsl/AutoBuildCancel"
Model: Entity | Statement;
Entity: 'ENTITY' name=ID atributes+=Atribute+;
Atribute: 'ATRIBUTE' name=ID;
Statement: 'STATEMENT' name=ID entity=[Entity];
And this generator
class AutoBuildCancelGenerator extends AbstractGenerator {
@Inject extension IQualifiedNameProvider
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
val model = resource.contents.get(0) as Model
fsa.generateFile(model.fullyQualifiedName.toString("/") + ".txt", model.toTest)
}
def dispatch CharSequence toTest(Entity entity) '''
ENTITY «entity.name»
«FOR attr : entity.atributes»
«attr.name»
«ENDFOR»
'''
def dispatch CharSequence toTest(Statement entity) '''
STATEMENT TO «entity.entity.toTest»
'''
}
A resource can contain a single Entity with some attributes or a single statement referencing an entity
The result of the compilation is the list of attributes in both cases.
E1 source
ENTITY E1
ATRIBUTE A1
ATRIBUTE A2
E1 generated
S1 source
S1 generated
STATEMENT TO ENTITY E1
A1
A2
Xtext handles changes pretty well because it knows that S1 references E1 and if i add a new attribute, E1 IResourceDescription changes and DefaultResourceDescriptionManager.isAffected can detect all resources that are affected.
The problem comes when the AutoBuild job is cancelled in the generation phase and changes to the IResourceDescription's are "commited".
In this case, the build starts again but it doesn't detect a change, so S1 is not generated.
To reproduce it:
* Close all open windows in the Eclipse editor used to test the language
* Open only E1, add a new attribute and save
* Both E1.txt and S1.txt have the new attribute
* Add a breakpoint in doGenerate
* Leave open again only E1, add another attribute and save
* While stopped in doGenerate, open S1. This causes the build to interrupt (discussion in here https://www.eclipse.org/forums/index.php/m/1773425/?srch=autobuild#msg_1773425)
* Continue doGenerate and XtextBuilder.handleCancelled is called
* Build starts again automatically but it doesn't detect the new attribute
* E1.txt has the new attribute but S1.txt does not
Should i open a ticket on github?
Last versions of Xtext (with lots of custom code) it's pretty fast, but the project i'm using is almost 12.000 files and 200Mb, so when this problem occurs and i have to do a full build, which takes more than 10 minutes (and then it has to do other things that take up 10 or 15 more minutes)
I've detected myself cancelations of the build because of:
* Eclipse JPA plugins https://www.eclipse.org/forums/index.php/t/1087065/ I've uninstalled them because i don't need them
* Subclipse used in the project: if i have the project in svn, it almost always cancels builds. I'm testing without it for now https://git.eclipse.org/r/#/c/101379/
* Opening a file https://www.eclipse.org/forums/index.php/m/1773425/?srch=autobuild#msg_1773425
Because of the combination of problems, i'm thinking that maybe i could customize Xtext to not honor build cancelation, but maybe is not posible ...
Any pointers to "live" with this problems would be greatly appreciated
Thanks,
Sergio
|
|
|
|
|
|
|
|
Re: DefaultResourceDescriptionManager.isAffected inconsistency when AutoBuild is cancelled [message #1786198 is a reply to message #1786009] |
Thu, 26 April 2018 17:17 |
Sergio Otero Messages: 39 Registered: June 2012 |
Member |
|
|
XtextBuilder has this function
private boolean shouldCancelBuild(int buildKind) {
return buildKind == IncrementalProjectBuilder.AUTO_BUILD && isInterrupted();
}
So it only cancels when the autobuild job has been interrupted with a job with more priority
Eclipse doc says "This method allows long running builders to respond to this interruption in a timely manner. Builders are not required to respond to interruption requests"
Because isInterupted is final and shouldCanceBuild is private, i have to override 3 methods
@Singleton
public class CustomXtextBuilder extends XtextBuilder {
private static final ThreadLocal<IProgressMonitor> threadLocalMonitor = new ThreadLocal<>();
@Override
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
try {
threadLocalMonitor.set(monitor);
return super.build(kind, args, monitor);
} finally {
threadLocalMonitor.remove();
}
}
@Override
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitorOld) throws CoreException {
IProgressMonitor monitor = threadLocalMonitor.get();
SubMonitor progress = SubMonitor.convert(monitor, 1);
try {
super.incrementalBuild(delta, progress.newChild(1));
} finally {
if (monitor != null)
monitor.done();
}
}
@Override
protected void fullBuild(IProgressMonitor monitorOld, boolean isRecoveryBuild) throws CoreException {
IProgressMonitor monitor = threadLocalMonitor.get();
SubMonitor progress = SubMonitor.convert(monitor, 1);
try {
super.fullBuild(monitor, isRecoveryBuild);
} finally {
if (monitor != null)
monitor.done();
}
}
class CustomOverridingModule extends AbstractGenericModule {
def override configure(Binder binder) {
super.configure(binder)
binder.bind(XtextBuilder).to(CustomXtextBuilder);
}
}
<plugin>
<extension
point="org.eclipse.xtext.ui.shared.overridingGuiceModule">
<module
class="org.xtext.example.mydsl.ui.CustomOverridingModule">
</module>
With this change, the problems seems to be solved.
The build is not interrupted with high priority jobs, but it still can be cancelled by the user
Sergio
|
|
|
Powered by
FUDForum. Page generated in 0.04185 seconds