Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Syncing different Parts together
Syncing different Parts together [message #1663497] Tue, 10 March 2015 12:55 Go to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Dear experts,
this is a more of a high-level design question.

I am building an E4 RCP application here, where I have a central GIS map and 1+ parts (eg JFace viewers) which I want to be tightly synchronized altogether.

I would like to ask to you all what would be your personal approach to this task, implementation-wise, keeping into account that performance counts here due to the heavy burden of map updates/editing.

I have the feeling that using a sort of "star-shaped" data-binding (1 observable model with N GUI elements on the other end) is the most robust method here, while playing with sending/posting events + DI is somewhat more loosely-coupled and more prone to errors.

How would you tackle this architecture?
How does Eclipse itself work it out?

Thanks for any help,
-Piero

[Updated on: Tue, 10 March 2015 13:39]

Report message to a moderator

Re: Syncing different Parts together [message #1668032 is a reply to message #1663497] Thu, 12 March 2015 09:49 Go to previous messageGo to next message
Mateusz Malinowski is currently offline Mateusz MalinowskiFriend
Messages: 36
Registered: March 2013
Location: Bristol
Member
Hi Piero,

I'm far from expert, but I'm more than happy to share with you my approach. Generally I have a model-view architecture. So whenever any part makes changes to it, it's their responsibility to trigger function, that will update all model listeners (all other parts + the one that made a change as well). This usually means that multiple threads are being created so not to lock the UI thread, and whenever thread finishes processing necessary data, it dispatches a runnable on UISynchronizer (can be injected in each part) to update controls, or to any other renderer thread. Also I quite a few things are stored in preferences which can than be injected in each part.

I hope that my input will be helpful,
Cheers!
Re: Syncing different Parts together [message #1668112 is a reply to message #1668032] Thu, 12 March 2015 10:34 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Thank you for sharing Mateusz,

so you have based your whole architecture on messages being sent over the event bus, where listeners react by using the @UIEventTopic annotation as method params. Is that correct?
I am however not sure about this UISynchronizer object you send around: are you using it explicitly?

Is that still reliable when you combine N fragment plugins in order to build an application? I mean, I guess so but I am experiencing unpredictable and somewhat aleatory behaviours here, maybe due to conflicts between plugins which share the same application context / event bus.

Sometimes I see as well that sending and posting an event via broker can produce very different results, and I am not sure about how the framework handles the buffers for asynchronized events down there, or how to control it.

Thank you very much for any hint, reference, or help,
-Piero



[Updated on: Thu, 12 March 2015 10:35]

Report message to a moderator

Re: Syncing different Parts together [message #1668861 is a reply to message #1668112] Thu, 12 March 2015 17:22 Go to previous messageGo to next message
Mateusz Malinowski is currently offline Mateusz MalinowskiFriend
Messages: 36
Registered: March 2013
Location: Bristol
Member
Hi Piero,

The @UIEventTopic is used purely for EventBroker, when it sends message to its listeners. Note, that this annotation forces that method to be run on UI thread. If you want to avoid that, just use @EventTopic. The latter creates a separate thread to handle the method.

EventBroker just sends data here and there. And it is bounded to those classes which have access to E4 Model (parts, handlers, addons, etc). I have a model that is a singleton class to be accessed by any other java class in my application. It also stores all most important data (e.g. some classes which are too big to be saved in preferences and can be easily instantiated at the application start-up). Now this singleton class provides a method to register a listener (interface with one method) and method that will trigger its listeners update method. This allows to transport data to all classes in the application.
Now UISynchronizer can be injected in any part. And if this part listens to your model updates, it will automatically receive new data. But this update doesn't happen on UI thread, so the UISynchronizer allows to dispatch runnable on the UI thread (synchronizer.async or something like that).
So generally, your data is being transported using as many non-UI threads as you want, and the UI thread will only update your controls, maps, etc. with current model state.
And this approach works well on application with multiple plugins and fragment.e4xmi files.

Send and post methods from EventBroker are quite nice for synchronisation, as one of them returns straight away, while the other blocks current thread. Just remember that when you use event broker from UI thread, not to block it. Otherwise you will have deadlock. There are many ways how you can exploit this functionality.

Mateusz
Re: Syncing different Parts together [message #1679151 is a reply to message #1668861] Mon, 16 March 2015 13:48 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Thanks Mateusz for your thorough explanation. Thumbs up Wink

-PIero
Re: Syncing different Parts together [message #1691720 is a reply to message #1668861] Thu, 09 April 2015 09:37 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Dear Mateusz + @all,

my experience so far pushes me to some confusion with regards to @EventTopic and @UIEventTopic.

While I successfully received a non-UI-related event (sent via broker within the same plugin/bundle) with my optional @EventTopic annotation in the handler, I could not receive an OSGi (sent via EventAdmin in an other plugin/bundle) with it.

Surprisingly changing my annotation to @UIEventTopic fix things.

Why is this happening? I was expecting a pure OSGi event to me more probably caught by an @EventTopic rather than UI event.

Thanks for your clarifications
-Piero

PS Declaring an event handler with OSGi XML component works fine too, but I like annotations more than DS since I can read the event ID right inside the handler and not somewhere else.
Re: Syncing different Parts together [message #1691726 is a reply to message #1691720] Thu, 09 April 2015 10:06 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2515
Registered: July 2012
Senior Member
I'm not sure about your implementation details. I recently published a blog post about sending events from OSGi declarative services.

https://blog.codecentric.de/en/2015/04/osgi-declarative-services-and-the-event-bus-eclipse-rcp-cookbook/

And after your post I added receiving the events in a method annotated with @EventTopic locally to see if I can reproduce your issue. But it works fine. So maybe you will find the missing part there.
Re: Syncing different Parts together [message #1691769 is a reply to message #1691726] Thu, 09 April 2015 14:30 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Thank you Dirk,
as you know already, I found it very useful Wink

Regarding this topic, still I double-checked all the conditions and there was nothing missing (apparently): I confirm that @EventTopic is broken, and additionally after a couple of successfull handling, neither the @UIEventTopic now is working.

Only the service component event handler successfully receives the event now: I can just stick to it but it would be highly educative to understand what is breaking up things here... There are some hidden factors here that go beyond single plugin configuration.

In general, there are frequent unexpected behaviours (of course, by no means dependent on Eclipse, certainly my misuse).
@Dirk: for instance, I tried to fetch the EventAdmin service programmatically from the bundle activator instead via DS, and I had to run it 2-3 times getting some NullPointerException before magically getting it to work smoothly (but without changing no-line): these kind of things. What are my colleagues and I missing?
Re: Syncing different Parts together [message #1691773 is a reply to message #1691769] Thu, 09 April 2015 14:50 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2515
Registered: July 2012
Senior Member
Quote:
I confirm that @EventTopic is broken, and additionally after a couple of successfull handling, neither the @UIEventTopic now is working


I don't understand what you mean. @EventTopic is broken? Going back to the topic of this thread, you want to sync parts, so why do you want to use @EventTopic? If you want to update UI elements you have to use @UIEventTopic because your code needs to be executed in the UI thread.

Quote:
I tried to fetch the EventAdmin service programmatically from the bundle activator instead via DS, and I had to run it 2-3 times getting some NullPointerException before magically getting it to work smoothly


There is no magic in software development, we just sometimes feel like magicians when things start to work. Wink
It sounds like some timing issue. Did you check your launch configuration and ensured that the necessary plugins are started in the correct order? The easiest way to set the recommended plug-in start levels is by clicking Add Recommended... in the Start Levels section of the Product Configuration Editor Configuration tab.

It should look similar to this:
   <configurations>
      <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
      <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
      <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
      <plugin id="org.eclipse.equinox.event" autoStart="true" startLevel="2" />
      <plugin id="org.eclipse.equinox.p2.reconciler.dropins" autoStart="true" startLevel="0" />
      <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
   </configurations>


If that doesn't work out, how do you try to fetch the EventAdmin service programmatically? Maybe you need another approach for this. Not sure if you already know that page, but I personally found this one really helpful: http://www.knopflerfish.org/osgi_service_tutorial.html#accessing
Re: Syncing different Parts together [message #1691851 is a reply to message #1691773] Fri, 10 April 2015 07:33 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Hi Dirk,
thanks again.

Well no: now both @EventTopic and @UIEventTopic do not work. I do not have to update the UI, I was just using the latter because it worked a couple of times at first before it would break without any explicit code/configuration change.

I take the EventAdmin service via the ServiceTracker, like done in the Eclipse EventBroker:

@SuppressWarnings({ "unchecked", "rawtypes" })
    public EventAdmin getEventAdmin() {
        if (eventAdminTracker == null) {
            eventAdminTracker = new ServiceTracker(bundleContext,
                    EventAdmin.class.getName(), null);
            eventAdminTracker.open();
        }
        return (EventAdmin) eventAdminTracker.getService();
    }


By now I'll just go with my handler declared as OSGi component, no big issue. If any further ideas come out, please post here. Thanks again to all of you Wink

[Updated on: Fri, 10 April 2015 07:34]

Report message to a moderator

Re: Syncing different Parts together [message #1691855 is a reply to message #1691851] Fri, 10 April 2015 07:54 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2515
Registered: July 2012
Senior Member
Hm, do you call getEventAdmin() every time you want to send something, or just once your service is created? It definitely sounds like an issue with bundle startup. If you don't specify the correct order, sometimes the event bundle will start before your bundle that contains your service, sometimes your bundle will start first.
Re: Syncing different Parts together [message #1692394 is a reply to message #1691855] Wed, 15 April 2015 12:58 Go to previous messageGo to next message
Piero Campalani is currently offline Piero CampalaniFriend
Messages: 110
Registered: January 2015
Senior Member

Hi Dirk,
just to close the discussion: no, I call it just once at bundle activation.

Thanks again for your support!
Re: Syncing different Parts together [message #1692413 is a reply to message #1692394] Wed, 15 April 2015 14:09 Go to previous message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2515
Registered: July 2012
Senior Member
Hi,

to finish this ... that is why you sometimes have the service and sometimes not. It is not guaranteed that the EventAdmin service is started and available when your bundle is activated. Since you only ask for it once, you are not notified when it is started. Using the service reference it gets bound when it is started.
Previous Topic:Create WorkbenchWindow as Modal
Next Topic:Adding plugin error
Goto Forum:
  


Current Time: Tue Oct 24 07:48:29 GMT 2017

Powered by FUDForum. Page generated in 0.02749 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software