Closed jukzi closed 5 months ago
org.eclipse.jdt.internal.core.CommitWorkingCopyOperation.getSchedulingRule()
uses modify rule (== current file) for already existing files, but new API in org.eclipse.core.resources.IFile.write(byte[], boolean, boolean, boolean, IProgressMonitor)
unconditionally calls org.eclipse.core.internal.resources.File.create(byte[], int, IProgressMonitor)
that needs also parent rule to be taken as is supposed to modify the parent state too (by creating a new child)
As a file doesn't pre-exist, the create
operation uses the parent project scheduling rule. Since write
calls create
it does use this parent project scheduling rule.
If the operation in process already uses the file scheduling rule (because it knows it will only modify this file), then trying to get a "bigger" scheduling rule for the operation will fail. As create
can now either create a new file or modify it, it's rule could probably be changed to final ISchedulingRule rule = exists() ? workspace.getRuleFactory().modifyRule(this) : workspace.getRuleFactory().createRule(this);
, or maybe just clearly have create
first line or so be if (exists() && (flags & REPLACE) != 0) { setContents(); }
to clearly split stuff.
The clearer documentation about scheduling rule is probably https://www.eclipse.org/articles/Article-Concurrency/jobs-api.html , but there are some other info available in the help such as https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2FresAdv_concurrency.htm or https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2FresAdv_batching.htm (the later is exactly describing what JDT is doing here: grouping several workspace changes to this file into a single operation, with the narrowest possible scheduling rule in order to allow more concurrent processing)
I am not used to that rules ... do you think it should be handled in JDT or does it need to be fixed in platform?
It should be changed in Platform so that editing an existing file should always use the modifyResource(file) rule. As suggested earlier, create
should probably be reorganized to just call the good old setContents
when file already exists, so it would behave exactly the same, not even changing the scheduling rule.
I am not used to that rules ... do you think it should be handled in JDT or does it need to be fixed in platform?
Platform. "Write" can't take "Create" rule, as the "Create" scope is bigger.
setContents
when file already exists, so it would behave exactly the same, not even changing the scheduling rule.
That would essentially revert the only review suggestion, i.e. also remove the potential usage of a CREATE REPLACE flag?
Yes, maybe it's simpler to just remove the usage of REPLACE (which doesn't bring much per se) and just make write
just delegate to setContents
or create
depending on exists()
thanks @mickaelistria and @iloveeclipse for your valuable input on this
Replacing IFile.setContents with IFile.write in org.eclipse.jdt.internal.core.Buffer.save(IProgressMonitor, boolean) causes a regression:
I will investigate. If someone has an idea: please share