Bug 547683 - A way to get ITextViewer selection out of UI thread
Summary: A way to get ITextViewer selection out of UI thread
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Text (show other bugs)
Version: 4.12   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 4.14 M1   Edit
Assignee: Mickael Istria CLA
QA Contact:
URL:
Whiteboard:
Keywords: api, noteworthy, plan
Depends on: 551109 551180
Blocks: 538656
  Show dependency tree
 
Reported: 2019-05-27 06:56 EDT by Mickael Istria CLA
Modified: 2019-10-07 03:38 EDT (History)
3 users (show)

See Also:
daniel_megert: review? (daniel_megert)


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mickael Istria CLA 2019-05-27 06:56:36 EDT
The methods to retrive selection in TextViewer should not require UI Thread, as it's easy to plug listener computing the value for those methods, and returning the pre-computed result on demand. The effort of computing the values seems small enough to happen on selection change.
Having them non-UI Thread would make some content-assist processor able to work without UI Thread.
Comment 1 Dani Megert CLA 2019-05-27 09:17:27 EDT
I doubt this can be done, but let's see.
Comment 2 Mickael Istria CLA 2019-05-27 09:40:13 EDT
(In reply to Dani Megert from comment #1)
> I doubt this can be done, but let's see.

Challenge accepted ;)
Comment 3 Eclipse Genie CLA 2019-05-27 10:23:44 EDT
New Gerrit change created: https://git.eclipse.org/r/142866
Comment 4 Mickael Istria CLA 2019-05-27 10:50:34 EDT
(In reply to Eclipse Genie from comment #3)
> New Gerrit change created: https://git.eclipse.org/r/142866

This is work-in-progress, one issue at the moment is that some events that trigger a selection change don't send a notification so widget is not updated.
Comment 5 Mickael Istria CLA 2019-05-28 03:29:06 EDT
I think there is no good way to implement it without risk on backward compatibility: there is no guarantee that the listeners used by this patch to store selection happen before other listeners that might invoke the getSelectedRange() or getSelection() methods, which would return different result before the internal listener is called. Also, those methods are API and the contract doesn't say it doesn't require UI Thread. So changing them in one implementation and assume those methods are in the general case good for usage in a non-UI Thread would be faulty.
As mentioned by Andrey in a previous comment IIRC, introducing a new method `getLastSelection()` on the interface, which we specify in the javadoc as not requiring UI Thread, seems to be a better way forward. We'd add a dummy default implementation, and a better working implementation in TextViewer. JDT could rely on this method to remove its adherence on UI Thread in completion computers.

What do you think?
Comment 6 Dani Megert CLA 2019-05-28 06:59:21 EDT
(In reply to Mickael Istria from comment #5)
> I think there is no good way to implement it without risk on backward
> compatibility: there is no guarantee that the listeners used by this patch
> to store selection happen before other listeners that might invoke the
> getSelectedRange() or getSelection() methods, which would return different
> result before the internal listener is called. Also, those methods are API
> and the contract doesn't say it doesn't require UI Thread. So changing them
> in one implementation and assume those methods are in the general case good
> for usage in a non-UI Thread would be faulty.
> As mentioned by Andrey in a previous comment IIRC, introducing a new method
> `getLastSelection()` on the interface, which we specify in the javadoc as
> not requiring UI Thread, seems to be a better way forward. We'd add a dummy
> default implementation, and a better working implementation in TextViewer.
> JDT could rely on this method to remove its adherence on UI Thread in
> completion computers.
> 
> What do you think?
I don't think this could solve the "listener problem".
Comment 7 Mickael Istria CLA 2019-05-28 08:34:47 EDT
Current version of the patch is ready for review (not an emergency).
Comment 8 Mickael Istria CLA 2019-06-28 06:25:58 EDT
Making it an API candidate for M1.
This API addition would be profitable for
1. Users for ContentAssistant in asynchronous mode (relying on generic editor or setting the flag to true), which want to provide content-assist proposals that depend not only on the offset, but also on the current selection (for example a completion with a whole word selected might be driving to computation of possible replacement instead of possible inserts), but that are not allowed to call methods requiring UI Thread.
2. in JDT (bug 538858) to replace usage of methods requiring API by this method so JDT proposal computation could happen in a non-UI Thread, without blocking UI.
Comment 9 Mickael Istria CLA 2019-06-28 06:34:08 EDT
(In reply to Mickael Istria from comment #8)
> Making it an API candidate for M1.
> This API addition would be profitable for
> 1. Users for ContentAssistant in asynchronous mode (relying on generic
> editor or setting the flag to true), which want to provide content-assist
> proposals that depend not only on the offset, but also on the current
> selection (for example a completion with a whole word selected might be
> driving to computation of possible replacement instead of possible inserts),
> but that are not allowed to call methods requiring UI Thread.
> 2. in JDT (bug 538858) to replace usage of methods requiring API by this
> method so JDT proposal computation could happen in a non-UI Thread, without
> blocking UI.

The reason why this might require review is that it creates a API breakage: in https://wiki.eclipse.org/Evolving_Java-based_APIs_2 
"""
(8) Adding a default method will break an existing client type if it already implements another interface that declares a default method with a matching signature, and the client type already refers to the default method from the other interface (except when using the Interface.super.method() notation). The added default method will cause an IncompatibleClassChangeError at run time, see JLS8 13.5.6. Furthermore, re-compiling the type will result in a compile error.

    In cases where the risk of multiple inheritance of the same method from multiple interfaces is deemed low and the added value is deemed sufficiently high, selected default methods can be added to existing interfaces. However, such a change should only be applied in an early milestone, and it should be reverted if clients report any difficulties with the change.
"""

With the current name (getLastKnownSelection), I couldn't find any hit on GitHub and searching 2 search engines (Qwant and Google) didn't find any hit neither.
So it seems to me that we're in the case where "the risk of multiple inheritance of the same method from multiple interfaces is deemed low", and the goal of this API method is IMO "deemed sufficiently high".
Comment 10 Mickael Istria CLA 2019-07-03 11:55:54 EDT
This will most likely miss M1 as I'd like to consolidate this proposal with examples of how it can enable JDT to become non-blocking.
Comment 11 Mickael Istria CLA 2019-07-04 06:25:14 EDT
In reply to Mickael Istria from comment #8)
> Making it an API candidate for M1.
(continued)

On the patch https://git.eclipse.org/r/142866 , I've added a test example showing the kind of things that this new API would enable in the Generic Editor (where completion runs in non-UI Thread): this methods allows to make some completion processor easily use the TextSelection from the viewer to generate their proposal. It's something that is not properly possible without the suggested change or a similar one: content assist processor cannot get the text selection.

In https://git.eclipse.org/r/142866 / Bug 538656, I've shown how this can be used in JDT to make it's current contentassistprocessors not requiring UI Thread. If you couple it with change https://git.eclipse.org/r/129022 / Bug 531061 then this enables JDT content assist to not block UI when computing proposals (similarly to generic editor, it would show the completion popup with a "computing" proposal while computing and then will show the list of proposals).
This ability to make JDT completion non-blocking also depends on this ability to get the selection from out of the UI Thread.
Comment 12 Dani Megert CLA 2019-07-10 06:33:28 EDT
-1 for adding the default method, especially since the default implementation is wrong in most cases. Clients using the new method can never be sure whether they get a correct result.

The correct way is to use the pattern we always use when adding new methods to an interface: add an extension interface ==> ITextViewerExtension9 (and let TextViewer implement it).

That way, clients can check whether the viewer implements that interface and a correct implementation of the method is available.
Comment 13 Mickael Istria CLA 2019-07-15 07:45:46 EDT
(In reply to Dani Megert from comment #12)
> -1 for adding the default method, especially since the default
> implementation is wrong in most cases. Clients using the new method can
> never be sure whether they get a correct result.
> 
> The correct way is to use the pattern we always use when adding new methods
> to an interface: add an extension interface ==> ITextViewerExtension9 (and
> let TextViewer implement it).
> 
> That way, clients can check whether the viewer implements that interface and
> a correct implementation of the method is available.

Thanks Dani, that's indeed better. I'll do that as soon as I have the opportunity (ETA end of this week)
Comment 14 Mickael Istria CLA 2019-07-16 12:34:50 EDT
(In reply to Mickael Istria - away until July 15th from comment #13)
> Thanks Dani, that's indeed better. I'll do that as soon as I have the
> opportunity (ETA end of this week)

latest patch set in https://git.eclipse.org/r/c/142866/ implements it with a ITextViewerExtension9. Would you like to give it a review?
Comment 15 Dani Megert CLA 2019-07-17 11:38:25 EDT
(In reply to Mickael Istria - away until July 15th from comment #14)
> You're still away ;-)

> Would you like to give it a review?
Yes, but it might take a while as I am in India with my team for the next 8 days.
Comment 16 Mickael Istria CLA 2019-07-17 12:07:27 EDT
(In reply to Dani Megert from comment #15)
> > Would you like to give it a review?
> Yes, but it might take a while as I am in India with my team for the next 8
> days.

Ok, that's fine.
Comment 17 Mickael Istria CLA 2019-08-09 09:50:11 EDT
@Dani: do you still want to have a look at the proposal? It'd be great if we could merge it for M3.
Comment 18 Mickael Istria CLA 2019-08-14 12:44:44 EDT
Since this is to late to roll out this change in Platform Text and then in JDT without risk, let's postpone it for 4.14.M1.
People are still encouraged the review the patch from now on; unless there are negative reviews, I'll merge it on the day 4.14 opens so we can adopt it in JDT ASAP with enough time for feedback.
Comment 19 Dani Megert CLA 2019-08-15 05:11:25 EDT
(In reply to Mickael Istria from comment #17)
> @Dani: do you still want to have a look at the proposal? It'd be great if we
> could merge it for M3.
Yes, it's in my big inbox. Sorry for the delay. 4.14 is a good plan.
Comment 20 Mickael Istria CLA 2019-09-11 10:22:04 EDT
(In reply to Dani Megert from comment #19)
> Yes, it's in my big inbox. Sorry for the delay. 4.14 is a good plan.

Is it OK for a merge today or tomorrow?
Comment 21 Eclipse Genie CLA 2019-09-13 11:56:07 EDT
New Gerrit change created: https://git.eclipse.org/r/149497
Comment 23 Andrey Loskutov CLA 2019-09-18 04:10:31 EDT
(In reply to Eclipse Genie from comment #22)
> Gerrit change https://git.eclipse.org/r/142866 was merged to [master].
> Commit:
> http://git.eclipse.org/c/platform/eclipse.platform.text.git/commit/
> ?id=b706c681d2e1dedf9cff05eb1a366db762abc8be

This breaks debugger, see bug 551180.

Debug Shell is unusable for me, and so I can't use SDK for development anymore. We urgently need to fix this or revert the change (note: bundle versions were updated, so if reverting, we must revert only code).
Comment 24 Mickael Istria CLA 2019-09-18 08:26:24 EDT
(In reply to Andrey Loskutov from comment #23)
> This breaks debugger, see bug 551180.

Thanks for catching that, I'll have a look but cannot promise immediate solution so...

> Debug Shell is unusable for me, and so I can't use SDK for development
> anymore. We urgently need to fix this or revert the change (note: bundle
> versions were updated, so if reverting, we must revert only code).

... I think reverting is worth it here. Feel free to revert and I'll try to cover the case of bug 551180 in some new version of the patch.
Comment 25 Andrey Loskutov CLA 2019-09-18 11:05:13 EDT
(In reply to Mickael Istria from comment #24)
> (In reply to Andrey Loskutov from comment #23)
> > This breaks debugger, see bug 551180.
> 
> Thanks for catching that, I'll have a look but cannot promise immediate
> solution so...
> 
> > Debug Shell is unusable for me, and so I can't use SDK for development
> > anymore. We urgently need to fix this or revert the change (note: bundle
> > versions were updated, so if reverting, we must revert only code).
> 
> ... I think reverting is worth it here. Feel free to revert and I'll try to
> cover the case of bug 551180 in some new version of the patch.

Mickael, I've merged now this patch:
https://git.eclipse.org/r/#/c/149729/
to fix Debug Shell bug 551180.

Please validate if and how this affects this implementation.
Comment 26 Mickael Istria CLA 2019-09-18 11:09:11 EDT
(In reply to Andrey Loskutov from comment #25)
> Mickael, I've merged now this patch:
> https://git.eclipse.org/r/#/c/149729/
> to fix Debug Shell bug 551180.
> Please validate if and how this affects this implementation.

Thanks. I'll check that when getting back to bug 528656.
Comment 27 Alexander Kurtakov CLA 2019-10-04 09:17:31 EDT
Mickael, what is the status here? Can it be resolved?
Comment 28 Mickael Istria CLA 2019-10-07 03:38:31 EDT
Yes, let's mark is a resolved. API is here and working (in the tests I've made with downstream JDT bugs). If some more issue happen with it, we'll open new tickets.