Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Remote Application Platform (RAP) » context and request service lifecycle connundrum
context and request service lifecycle connundrum [message #648444] Wed, 12 January 2011 22:57 Go to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Hi all,

I'm looking at the FAQ re: getting session store and in general working with UI thread. This is what is suggested on getting the exception: Caused by: java.lang.IllegalStateException: No context available outside of the request service lifecycle..

"The soltion is to wrap your code in a Runnable and have it executed by UICallBack#runNonUIThreadWithFakeContext()."

But when I try something like:

final Display display = new Display();
				  UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {


I get the same context error, but this time from the call to new Display(); So I'm sort of stuck in a loop there..perhaps I have something misconfigured somewhere.

On a more or less different topic, what do people think would be the best strategy for obtaining and storing an OAuth for an API service such as Twitter? Should I be using an IServiceProvider or what, given that the OAuth service needs to have user approval?

thanks for any help,

Miles
Re: context and request service lifecycle connundrum [message #648464 is a reply to message #648444] Thu, 13 January 2011 02:22 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Prob. could use a little more detail on this..the issue is that it looks like display creation wants to figure out DPI, but it needs a context for that! And again from FAQ it looks like we need a display to get the context.

I did read http://wiki.eclipse.org/RAP/FAQ#Why_does_Display.23getDefaul t.28.29_work_different_than_in_SWT as well, but there is a similar issue there.. "As a consequence, getDefault() can only create a Display instance if it is called from the user-interface thread." But how can I get into user interface thread..the only way I know how to do that is through async/syncExec, and that requires a display! Clearly I'm missing something obvious here..

Caused by: java.lang.IllegalStateException: No context available outside of the request service lifecycle.
	at org.eclipse.rwt.internal.service.ContextProvider.getContext(ContextProvider.java:107)
	at org.eclipse.rwt.internal.service.ContextProvider.getRequest(ContextProvider.java:123)
	at org.eclipse.swt.graphics.Device.readDPI(Device.java:374)
	at org.eclipse.swt.graphics.Device.<init>(Device.java:40)
	at org.eclipse.swt.widgets.Display.<init>(Display.java:232)
	at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:465)
	at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:168)
Re: context and request service lifecycle connundrum [message #648468 is a reply to message #648464] Thu, 13 January 2011 03:09 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Continuing this fascinating conversation with myself, I figured that perhaps the only way around this issue was to provide some path to get at the display from the original event source, which of course would have to have a UI. This is not really preferable, because it requires a bit of mixing in UI where it isn't needed, and I won't always be launching from a UI context but it works for now.

In my case, I need my functionality from within EMF commands. In normal use these commands will be trigged by UI handlers, so I keep optional state for the editor part in the command and set it from the handler. Then I can use the part to get at the shell. It would still be nice to have equivalent functionality to Display.getDefault() available form RAP.
Re: context and request service lifecycle connundrum [message #648795 is a reply to message #648468] Fri, 14 January 2011 14:27 Go to previous messageGo to next message
Paul Bilnoski is currently offline Paul BilnoskiFriend
Messages: 28
Registered: August 2010
Junior Member
Miles Parker wrote on Wed, 12 January 2011 22:09
Continuing this fascinating conversation with myself, I figured that perhaps the only way around this issue was to provide some path to get at the display from the original event source, which of course would have to have a UI. This is not really preferable, because it requires a bit of mixing in UI where it isn't needed, and I won't always be launching from a UI context but it works for now.

In my case, I need my functionality from within EMF commands. In normal use these commands will be trigged by UI handlers, so I keep optional state for the editor part in the command and set it from the handler. Then I can use the part to get at the shell. It would still be nice to have equivalent functionality to Display.getDefault() available form RAP.


The main question RAP needs to know when you are getting a display is "which Display?" In SWT, you only have the one display thread, so static access can be allowed. In RAP, each client that connects gets a new Display, and many operations should not apply equally to all displays. One user's operation may effect the others by causing a refresh, but for example an asynchronous operation resulting in an error dialog should only go to the user that invoked the operation.

Here are some solutions for the "which display?" problem.
1)
You have already discovered one option - passing a Display or Shell reference from the UI handler to the object which is the eventual recipient of the message that needs a Display reference.
2)
The recipient of the message is notified outside the display thread, but is a "resident" of the Display. Meaning it is a view part, or some other workbench or UI component that is tied to the lifecycle of the Display, and has previously somehow registered to receive an event from another thread, such as registering as an OSGi listener-service. When creating controls, store the toplevel control in a field. When the notification is received, use the part's toplevel control to access its Display.
3)
A solution in an application my team has come up with is to register each Display (we actually register the IWorkbench) as it comes up in a back-end registry as a custom "WorkbenchProvider" interface.
When a back-end event is fired, a listener iterates through all registered providers and tests criteria in the event against each provider to discover the correct one on which to process the event. This is typically based on the logged-in user's ID. We do this to handle network traffic to keep remote clients in sync when the Display cannot simply be attached to the event notification and serialized.
We store the workbench and not simply the display to have access to any other workbench services that may be useful and are safe to use outside the display thread, as well as the ability to get its display through IWorkbench.getDisplay()

--Paul
Re: context and request service lifecycle connundrum [message #648868 is a reply to message #648795] Fri, 14 January 2011 18:57 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Paul Bilnoski wrote on Fri, 14 January 2011 09:27

The main question RAP needs to know when you are getting a display is "which Display?" In SWT, you only have the one display thread, so static access can be allowed..


Yes that makes sense. You guys have certainly put a lot of thought into this -- it's amazing given the limitations of the browser metaphor that you've been able to get the vast majority of functionality covered identically.

Thanks for all of the solution ideas. I thought of one other variation on 1) that would be more maintainable. Rather than the handler setting the value directly, it could register the view part as an adapter for the command. Then, if the view part is available, the command could update using the UI thread but otherwise throw a status or workaround as appropriate.

If one wanted to go really crazy you could instead create a UI delegate adapter for the command with a reference to the view part and the command, That would allow the UI dependency and code for the command code to be avoided altogether, but it's pretty anoid.

[Updated on: Fri, 14 January 2011 18:59]

Report message to a moderator

Re: context and request service lifecycle connundrum [message #649048 is a reply to message #648868] Mon, 17 January 2011 12:15 Go to previous messageGo to next message
Ralf Sternberg is currently offline Ralf SternbergFriend
Messages: 1313
Registered: July 2009
Senior Member

Hi Miles,

I still don't understand where you put this code in question. You seem to
be running some code in a non-UI thread and try to find the display of a
certain user session, right?

Maybe it would help if you explain your use case or show a code snippet
with some more context.

Best regards, Ralf

--
Ralf Sternberg

Twitter: @ralfstx
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Re: context and request service lifecycle connundrum [message #649568 is a reply to message #649048] Wed, 19 January 2011 18:11 Go to previous messageGo to next message
Miles Parker is currently offline Miles ParkerFriend
Messages: 1341
Registered: July 2009
Senior Member
Ralf Sternberg wrote on Mon, 17 January 2011 07:15

I still don't understand where you put this code in question. You seem to
be running some code in a non-UI thread and try to find the display of a
certain user session, right?



Hi Ralf,

It's a bit more complicated than that -- in fact the call chain would be too complex to go through here. But in broad outline the idea is that we have an EMF command: EMF commands do not have to be UI related, and in fact it is a very useful case to have them available in a non-UI context, as they allow you to do things like roll-back, caching, asynchronous updating, etc.. and manage all of the tricky model updating bits consistently. *But* one of the EMF commands requires authentication, and in the case where we do have a user id, it's appropriate to do authentication from a user context. What this means is that we go from:

1) User triggers command.
2) Command is executed in non-UI context as an Eclipse job.
3) Command may trigger user authentication.
4) At that point we then need to present User with a dialog or whatever. (This is where opening the separate URL comes in to play, because we need to obtain a token from the URL and somehow get it back to the Server session. That's super tricky it turns out.)

Anyway, what I worked out with all of this was to implement the command so that it optionally adapts to the initial viewpart from 1. That seems to work fine so far.

Re: context and request service lifecycle connundrum [message #650015 is a reply to message #649568] Fri, 21 January 2011 13:23 Go to previous message
Ralf Sternberg is currently offline Ralf SternbergFriend
Messages: 1313
Registered: July 2009
Senior Member

Hi Miles,

good that it works for you now. The key point is that you need some way
of maintaining the reference to the user session (i.e. the display) and
pass it to the code running in the non-UI thread to be able to modify
this user's UI from the background.

Regards, Ralf

--
Ralf Sternberg

Twitter: @ralfstx
Blog: http://eclipsesource.com/blogs/

Professional services for RAP and RCP?
http://eclipsesource.com/services/rap/
Previous Topic:URL Encoding
Next Topic:Multitab browsing
Goto Forum:
  


Current Time: Thu Apr 25 19:55:46 GMT 2024

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

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

Back to the top