FX Application startup & threads [message #1386051] |
Fri, 13 June 2014 04:37  |
Eclipse User |
|
|
|
Hi,
We noticed that all the E4 FX application startup (more precisely, the application model initialization) happens in the FX event thread : model assembling, processor & addons executions, etc.
During this process, we wanted to keep a login dialog visible and alive (i.e. showing a progress indicator), so we modified the E4Application.jfxStart() method to do all this in another thread, and finally just run the workbench.createAndRunUI() in the FX thread.
This works fine for us and has the following advantages :
- the FX thread can continue UI rendering during the startup phase (i.e. our login dialog can continue show progress information)
- In the case custom addons/processors are long to execute (e.g. requiring remote services, etc.), this allows to follow progress on a UI
- when closing the "progress UI" on the applicationRunning event, main UI shows up quasi instantly.
What changes is that (may not be exhaustive) addons, processors and lifecycle methods @processRemovals and @processAdditions do no more run on the UI thread, but we guess this is not really a problem as no rendering operation should performed there.
As said this works fine for us, does one see any problem this could lead to, or use cases this could break ?
If not, couldn't this be an enhancement ?
Our modified E4Application.jfxStart() method below :
@Override
protected void jfxStart(IApplicationContext applicationContext, Application jfxApplication, Stage primaryStage) {
Runnable startRunnable = new Runnable() {
@Override
public void run() {
workbench = createE4Workbench(applicationContext, jfxApplication, primaryStage);
if (workbench != null) {
instanceLocation = (Location) workbench.getContext().get(E4Workbench.INSTANCE_LOCATION);
try {
if (!checkInstanceLocation(instanceLocation)) {
return;
}
workbenchContext = workbench.getContext();
// Create and run the UI (if any)
UISynchronize uiSync = workbench.getContext().get(UISynchronize.class);
uiSync.syncExec(new Runnable() {
@Override
public void run() {
workbench.createAndRunUI(workbench.getApplication());
}
});
} finally {
applicationContext.applicationRunning();
}
}
}
};
Thread t = new Thread(startRunnable);
t.start();
}
Sun
|
|
|
Re: FX Application startup & threads [message #1386056 is a reply to message #1386051] |
Fri, 13 June 2014 05:04   |
Eclipse User |
|
|
|
Sounds reasonable - file a bug and if possible provide a gerrit-review
and we can merge that in.
Maybe we should add the possibility for developers to define how the
start up process should be handled?
The only change i would make is to call
"applicationContext.applicationRunning(); " in the UI-Thread. The reason
for that is that people who use the Eclipse-Splash (only win32 users can
do that today!) need this method to be called on the launcher thread or
the splash will not close.
Tom
On 13.06.14 10:37, Sun Volland wrote:
> Hi,
>
> We noticed that all the E4 FX application startup (more precisely, the
> application model initialization) happens in the FX event thread : model
> assembling, processor & addons executions, etc.
> During this process, we wanted to keep a login dialog visible and alive
> (i.e. showing a progress indicator), so we modified the
> E4Application.jfxStart() method to do all this in another thread, and
> finally just run the workbench.createAndRunUI() in the FX thread.
>
> This works fine for us and has the following advantages :
> - the FX thread can continue UI rendering during the startup phase (i.e.
> our login dialog can continue show progress information)
> - In the case custom addons/processors are long to execute (e.g.
> requiring remote services, etc.), this allows to follow progress on a UI
> - when closing the "progress UI" on the applicationRunning event, main
> UI shows up quasi instantly.
>
> What changes is that (may not be exhaustive) addons, processors and
> lifecycle methods @processRemovals and @processAdditions do no more run
> on the UI thread, but we guess this is not really a problem as no
> rendering operation should performed there.
>
> As said this works fine for us, does one see any problem this could lead
> to, or use cases this could break ? If not, couldn't this be an
> enhancement ?
>
> Our modified E4Application.jfxStart() method below :
>
>
> @Override
> protected void jfxStart(IApplicationContext applicationContext,
> Application jfxApplication, Stage primaryStage) {
> Runnable startRunnable = new Runnable() {
> @Override
> public void run() {
> workbench = createE4Workbench(applicationContext,
> jfxApplication, primaryStage);
> if (workbench != null) {
> instanceLocation = (Location)
> workbench.getContext().get(E4Workbench.INSTANCE_LOCATION);
>
> try {
> if (!checkInstanceLocation(instanceLocation)) {
> return;
> }
>
> workbenchContext = workbench.getContext();
>
> // Create and run the UI (if any)
> UISynchronize uiSync =
> workbench.getContext().get(UISynchronize.class);
> uiSync.syncExec(new Runnable() {
> @Override
> public void run() {
>
> workbench.createAndRunUI(workbench.getApplication());
> }
> });
>
> } finally {
> applicationContext.applicationRunning();
> }
> }
> }
> };
> Thread t = new Thread(startRunnable);
> t.start();
> }
>
>
>
> Sun
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: FX Application startup & threads [message #1386572 is a reply to message #1386563] |
Wed, 18 June 2014 05:54   |
Eclipse User |
|
|
|
Hi,
I think the solution must be different - I'm not sure we could get that
from upstream but we could implement it on our ScopedObjectFactory
ourselves for now.
The really important code is at - InjectorImpl.invokeUsingClass() we
could copy that code to our own factory and read the meta informations
about invocation.
I'll try to prototype this later on to see if it is possible, maybe we
could convince upstream that they modify their code a bit so that adding
a method
public MethodRequestor invokeUsingClass(Object userObject, Class<?>
currentClass, Class<? extends Annotation> qualifier, Object
defaultValue, PrimaryObjectSupplier objectSupplier,
PrimaryObjectSupplier tempSupplier, boolean throwUnresolved) {
// ...
}
so that we don't have to duplicate stuff - naturally we are with that
outside the API scope and I don't know if we have access to all APIs we
need without residing to reflection.
Tom
On 18.06.14 11:27, Christoph Keimel wrote:
> Hi Tom,
>
> I had a look at extending CIF the way you proposed below, because that
> would also elegantly solve this issue. I was thinking about extending
> the IInjector with the proposed functionality. This seems to be rather
> difficult at the moment, since the IInjector used in CIF is implemented
> as a Singleton.
>
> final private static IInjector injector = InjectorFactory.getDefault();
> I created a proposal to publish IInjector as an OSGi service upstream:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=437657
>
> This would enable us to create an extended service, no? Or am I missing
> something in my train of thought?
>
> Smile,
> Christoph
>
> Thomas Schindl wrote on Tue, 17 June 2014 13:31
>> Generally speaking I'd like to have a possibility when stuff is invoked
>> via CIF.invoke to mark that the method has to called on the UI-Thread in
>> a syny/async fashion.
>>
>> I dream of something like this:
>>
>> @Execute
>> @UISync
>> public String bla() {
>> }
>>
>> and
>>
>> @Execute
>> @UIAsync
>> public Future<String> bla() {
>> }
>>
>> Tom
>
|
|
|
|
|
|
|
|
|
Re: FX Application startup &amp;amp;amp;amp;amp; threads [message #1694138 is a reply to message #1693799] |
Thu, 30 April 2015 16:27  |
Eclipse User |
|
|
|
On 28.04.15 13:52, Bastien Bart wrote:
> I launch my app with -createWorkbenchOnNonUIThread argument.
>
> I want to block the loading of the workbench while my user is not logged
> (OK with your solution)
> But I want my login stage stays opened during the loading of the
> workbench. And that's not possible with the showAndWait method
>
> 1) Show login stage and block workbench launching
> 2) the user connects
> 3) The workbench launchs but the stage is still visible and shows
> launchings messages
> 4) Workbench loading done -> close the login stage
>
> There is a way to get this?
>
Only with the internal API that has been used by the block
implementation - so you need to call
Toolkit.getToolkit().enterNestedEventLoop(...);
Toolkit.getToolkit().exitNestedEventLoop(...);
yourself
> I think i'm not the only one who'd like a solution...
> Thanks a lot for your help
>
Tom
|
|
|