Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform element changes always in a non UI thread #1916

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

laeubi
Copy link
Contributor

@laeubi laeubi commented Jan 9, 2025

Currently PackageExplorerContentProvider receives events for changed elements from different threads and already has handling to perform only certain actions in the UI thread. But it does not really account for the case when the event itself is triggered from the UI thread in which case lengthy operation can take place in the UI.

This now checks if the change is using the UI and otherwise schedules a job to perform the required actions in the background.

See for example:

@jukzi
Copy link
Contributor

jukzi commented Jan 9, 2025

JavaElementDelta is not thread safe. the initialization may take place after it is used by another thread :-(

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

JavaElementDelta is not thread safe. the initialization may take place after it is used by another thread :-(

Can you give a concrete example where this can happen?

@iloveeclipse
Copy link
Member

This test is failing: ContentProviderTests3.testDeleteBottomLevelFragmentFolding
Which is OK considering the code changes the behavior and test runs in UI thread by default, but it has to be adopted.

Beside this (and missing "system" job flag) the change goes in the right direction.

The delta itself should be immutable after sending, so I do not see issues with that, however there might be multiple deltas, and so the dedicated job should be re-scheduled with the updated list of deltas to process, something like org.eclipse.jdt.ui.ProblemsLabelDecorator.AdornmentCalculationJob.

@jukzi
Copy link
Contributor

jukzi commented Jan 9, 2025

The delta itself should be immutable

The members need to be marked final or synchronized

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

I have poked around a bit more and actually the source seem to be the java editor performs "MakeWorkingCopy" operation and this triggers the an POST CHANGE event and then the whole thing runs inside the context of the Editor

I created now

to see what happens if we perform it async but it seems all not very optimal here, the Javadoc of the IJavaElementDelta say it is only valid during the callback, so actually one would need to copy all interesting data first.

Beside that I get the impression that the actual event is not really interesting for the package explorer anyways, but I have not enough insights to judge if thats the case and how it can be detected earlier.

@jukzi
Copy link
Contributor

jukzi commented Jan 9, 2025

I think you step back a bit to think what should happen/shown: When the javamodel is not up to date and things are displayed based on an outdated model they are either wrong drawn or need to be drawn again once the model is updated. Wrong data shown is wrong. Draw again may reduce a ui freeze but may in sum perform slower. The only clean solution would be to not show javamodel depended stuff until the model is (asnychronous) updated and then draw the java depended stuff once finished. That can not be archived by just deferring some calls but you would need to explicitly render java independend first. Possibly an explicit "loading..." text instead of showing a wrong (not) formatted sourcecode

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

Feel free to all implement that, I can only tell that the code here do not is designed to run in the UI, so this is not about presentation (what already is rendered in the UI once the changes are applied).

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

Fails existing tests...

@laeubi laeubi closed this Jan 9, 2025
@iloveeclipse
Copy link
Member

Fails existing tests...

This is expected and OK, only one test should be updated.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

Maybe someone can pick this up as an idea an polish this, I'm not sure how to best adjust the test or handle the concerns regarding usage of the Delta outside of event notification.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

Beside this, this one was the most promising experiment as indeed the UI is actually shown (even though other tasks are still execute in the UI) in contrast to that the UI is not shown before.

@iloveeclipse
Copy link
Member

Beside this, this one was the most promising experiment as indeed the UI is actually shown (even though other tasks are still execute in the UI) in contrast to that the UI is not shown before.

I strongly believe that this is doable and right way to go & encourage you to follow up on this PR.

@laeubi laeubi reopened this Jan 9, 2025
@laeubi laeubi force-pushed the asnyc_exec_update branch 2 times, most recently from 02f7174 to 70ffedf Compare January 9, 2025 17:14
@laeubi
Copy link
Contributor Author

laeubi commented Jan 9, 2025

I tried to adjust the one failing test but for me it seems the testcase itself depends on other places on synchronous event execution as well... it even seem that this particular test has a misplaced contruct ...

@laeubi
Copy link
Contributor Author

laeubi commented Jan 10, 2025

@iloveeclipse I think this should be merged before as it seems the main reason for the test failure:

Currently PackageExplorerContentProvider receives events for changed
elements from different threads and already has handling to perform only
certain actions in the UI thread. But it does not really account for the
case when the event itself is triggered from the UI thread in which case
lengthy operation can take place in the UI.

This now checks if the change is using the UI and otherwise schedules a
job to perform the required actions in the background.
@laeubi laeubi force-pushed the asnyc_exec_update branch from 70ffedf to f361f4b Compare January 10, 2025 13:03
@laeubi laeubi requested a review from iloveeclipse January 10, 2025 13:08
@laeubi
Copy link
Contributor Author

laeubi commented Jan 10, 2025

I hopefully have now addressed all concerns.

@laeubi laeubi requested a review from vogella January 10, 2025 13:19
Copy link
Contributor

@jukzi jukzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think, that JavaElementDelta has to be made threadsafe first (i.e. declare members final) and that after Deltas are applied the UI has to be refreshed somehow to not show an outdated state. The later should be verified by a Junit test.

public void run() {
try {
Job.getJobManager().join(PackageExplorerContentProvider.class, new NullProgressMonitor());
} catch (OperationCanceledException | InterruptedException e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not ignore unexpected exceptions but at least log them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anything goes wrong here the test will simply fail and one has to investigate that, I don't think that any logmessage is useful here.

@laeubi
Copy link
Contributor Author

laeubi commented Jan 10, 2025

I still think, that JavaElementDelta has to be made threadsafe first

I would then assume this will be taken by a JDT developer in advance, this PR is all I can currently offer here and it solves the issue for my testcase. @iloveeclipse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants