Bug 566754 - [Databinding 2.0] allow getter/setter to be called from outside the realm
Summary: [Databinding 2.0] allow getter/setter to be called from outside the realm
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.14   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Platform-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 566750
  Show dependency tree
 
Reported: 2020-09-08 01:35 EDT by Christoph Laeubrich CLA
Modified: 2020-09-21 10:50 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christoph Laeubrich CLA 2020-09-08 01:35:46 EDT
One of the most annoying things IMO currently is the "only call from realm concept".

Almost all implementations of the interfaces state that

> This class is thread safe. All state accessing methods must be invoked
> from the {@link Realm#isCurrent() current realm}.
> Methods for adding and removing listeners may be invoked from any thread.

So first of all its a bit hilarious to state a class is thread safe but require most of its methods to be executed inside a (single threaded) realm, even worse the API interfaces do not put such a restriction on the consumer so a user has to KNOW what implementation is used beforehand when accessing such an interface or will be thrown an exception when using this "thread-safe" class in a multi-threaded environment.

This "safety" is currently archived by calling all and everywhere (but not consistently everywhere...) a checkRealm() method that executes an Assert that the realm is the current one.

So in fact to really use an Observable in a possible multi-threade environment and the user can't be sure that its on the real-thread atm the user-code has to be decorated with a myriad a boilerplate-code checking for the realm, execute there, keep track of possible return values to hand over to the outer code and so on.

I'd like to propose a different approach given the fact that the code already does all that checking to take the logical consequence in the following way:

Instead of checkRealm we should add a set of methods to the realm itself that allows to execute a method inside the realm and return a value similar to the current run() method but with one difference: if the current realm is the realm it will be executed directly and if not the method is called in the realm waiting for the result.

Then an implementation can simply call for example to be sure to execute the method inside the realm:

> public X setValueAndReturnSomething() {
>    return getRealm().execute(this::doSetAndGet);
> }

more sophisticated implementations even might embody lock-free methods to update the value atomically and only call the listeners inside the realm.
Comment 1 Eclipse Genie CLA 2020-09-18 16:42:13 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/169603
Comment 2 Jens Lideström CLA 2020-09-18 16:47:56 EDT
I don't understand exactly what you are proposing...

I think it sound like a good idea to at least add a method to Realm that helps users to call a method from another thread and return a value.

The following change contains a simple work-in-progress implementation of such a method:

https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/169603

The new method would be used like this:

    int s = list.getRealm().execAndGet(list::size);

Would such a method solve at least some of your problem, Christoph?
Comment 3 Christoph Laeubrich CLA 2020-09-19 06:29:07 EDT
At least it is a good starting point, thanks :-)
Comment 4 Jens Lideström CLA 2020-09-19 16:06:59 EDT
I created bug 567152 specifically for this.
Comment 5 Jens Lideström CLA 2020-09-19 16:11:18 EDT
Maybe we should also clarify the misleading Javadoc about thread safety on observables...
Comment 6 Thomas Schindl CLA 2020-09-21 02:30:04 EDT
this is just a general comment on synchronized access. This is discouraged pattern to support because it can easily lead to deadlocks so modern APIs try to avoid it, if you introduce APIs like that you should at least explicitly state in the JavaDoc the possibility of deadlocks.
Comment 7 Jens Lideström CLA 2020-09-21 10:50:31 EDT
(In reply to Thomas Schindl from comment #6)

> This is discouraged pattern to support because it can easily lead to deadlocks

This is a good point indeed!

If it is possible then it is probably almost always better to implement updates across threads using asynchronous message passing.

> if you introduce APIs like that you should at least explicitly state in the JavaDoc the possibility of deadlocks.

I will do this for the change I'm working on right now:

https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/169603