Re: How to Retrieve Session User?
Re: How to Retrieve Session User?
- Subject: Re: How to Retrieve Session User?
- From: Chuck Hill <email@hidden>
- Date: Thu, 5 Apr 2007 09:49:16 -0700
On Apr 5, 2007, at 5:58 AM, Jean-François Veillette wrote:
Thanks Mike, I have a better picture now of what/where/how
ERXThreadStorage is helping.
I still think that I don't want per thread storage, we already have
request.userInfo for that and I use it only for web/request related
informations (used at the interface layer only).
I still feel uncomfortable with this concept, but I might give it a
try, I might feel better with this design once I use it in a real
project.
At the business layer (outside of a wo / rrl context) the concept
of thread doesn't hold as much (unless it's part of your business).
I don't see why that is true. We are talking about java.lang.Thread,
no WOWorkerThread. A java.lang.Thread is the context of execution of
Java code. It is the context of execution that is relevant here.
Chuck
I would tend to think that the use of thread specific storage is
kind of strange and not what I want at that level.
Ideally all I need is a userInfo dictionary from an editingContext,
because there is lots of business related context informations that
could be put in there.
- jfv
Le 07-04-05 à 07:52, Mike Schrag a écrit :
It is almost what I had in mind, only that I don't want a
different map per thread, I need a single map no mater how many
threads.
Why would we want a different map per thread when you use the
editing context as a key ?
When you receive a request (worequest), you have to set the map
every time, no ? (note that it's not worse than adding an entry
for every new eoeditingcontext)
ERXThreadStorage has a ThreadLocal in it. A ThreadLocal contains
a single object, uniqued by the thread it was assigned on. ERX
automatically pushes a dictionary into the ThreadLocal at the
start of the RR, and automatically removes the dictionary at the
end of the RR loop (i.e. 1 op at the start, 1 op at the end).
This is really handy for any number of "thread global" things
(hence why it's a map and not just the one object) -- WOSession,
WOContext, current user, etc. For instance, we have EO's that can
trigger notifications. It's useful to be able to access the
WOContext (if it exists) so we can clone it and get the original
context request URI, etc so that URLs built in the component
emails match the URL that the user came in on.
ERXThreadStorage is actually (by default) an
InheritableThreadLocal, so when you make a new thread, the
dictionary is cloned onto the new thread. Note that the contents
are not cloned, just the dictionary.
You must be careful about this, because you don't necessarily own
the editing context of an EO that's in this map, and you should
NOT access ERXExtensions.session() on the new thread (session is
automatically put in the threadstorage for you). This is because
the session may actually be expired, so you can't depend on it
being in a live state in this new thread. Additionally with
respect to EO's, the editing context may be disposed for the
object. The only truly threadsafe way to deal with this is
something like:
public static MyRunnable implements Runnable {
private EOGlobalID _userGID;
public MyRunnable(EOGlobalID userGID) {
_userGID = userGID;
}
public void run() {
ERXThreadStorage.removeValueForKey("session"); // not required,
but just so nobody gets any crazy ideas
ERXThreadStorage.removeValueForKey("wocontext"); // not
required, but just so nobody gets any crazy ideas
EOEditingContext ec = ERXEC.newEditingContext();
ec.lock();
try {
EOEnterpriseObject user =
ERXEOGlobalIDUtilities.fetchObjectWithGlobalID(ec, _userGID);
ERXThreadStorage.takeValueForKey(user, "user");
// perform your operation
}
finally {
ec.unlock();
}
}
}
...
public WOActionResults someRRMethod() {
EOEnterpriseObject user = (EOEnterpriseObject)
ERXThreadStorage.valueForKey("user");
EOGlobalID gid = user.editingContext().globalIDForObject(user);
Thread anotherThread = new Thread(new MyRunnable(gid));
anotherThread.start();
return null; // :) four keystrokes saved!
}
NB: in the RR method, I didn't lock, because Wonder locked for
me. In the other thread, depending on the settings you have, it
MAY be doing per-call locking for you, but I generally do a top
level lock anyway just to get a full transaction lock to be safe
(if you turn on lock coalescing, for instance, you definitely want
to be careful not being in an RR thread -- I believe that keys off
of having an wocontext on your thread).
ms
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40global-village.net
This email sent to email@hidden
--
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden