-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Olaf,

On 1/18/18 1:28 PM, Olaf Kock wrote:
> 
> On 18.01.2018 06:37, Christopher Schultz wrote:
>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>> 
>> Mark,
>> 
>> On 1/17/18 4:31 PM, Mark Thomas wrote:
>>> On 17/01/18 17:05, Christopher Schultz wrote:
>>>> All,
>>>> 
>>>> I have a use-case related to caching where I need to make
>>>> sure that an operation only happens one time with respect to
>>>> an object in the session. Basically, I want to build a cache
>>>> and put it into the session, but it needs to be thread-safe
>>>> enough that two threads can't see the object isn't there,
>>>> build such an object, and then put it into the session
>>>> (thereby overwriting each other).
> 
> ...
>>>> Yeah, I figured that. Otherwise, multi-threading basically
>>>> couldn't happen. I'm surprised the servlet spec doesn't
>>>> formally guarantee this because practically speaking, it's a
>>>> requirement.
> ....
>>> It should always be the same object. Looking at the code, I
>>> don't see any obvious holes.
>>> 
>>> For the record, relevant code includes: 
>>> o.a.catalina.connector.Request.getSession() 
>>> o.a.catalina.session.ManagerBase.createSession(String) 
>>> o.a.catalina.session.StandardSession.getSession()
>> Could this be something we could formally guarantee (via 
>> documentation)? I'd like to lobby the servlet EG for the same 
>> guarantee, but getting it done in Tomcat is more immediately
>> valuable for me :)
> I'm not sure that this can be done in an unambiguous way,
> especially not from the spec side: Assuming that objects might be
> serialized out to disk (for memory reason, unused in 15 minutes but
> not yet expired, cluster distribution etc) this would lead to quite
> a few disambiguities. You say that your object creation should
> happen once per session - is that per session AND machine? If
> creation of that object has side effects, or the object itself has
> state, your scenario might only be safe as long as there's no
> clustering / session replication involved, but can't be assumed
> when it is.

I would think the language would be something like "session objects
within the JVM shall be == equals to each other when requested from
the container" but I didn't think about the "serializing to [eg] disk"
scenario. If you have a session obtained from the container, then have
a long-running request or websocket handler and the container
meanwhile persists the session elsewhere, some other thread would
almost certainly get an object that is != the session object in the
other thread.

Hmm. I wonder if that is a problem, now, for Tomcat.

The container is only "maintaining" a single session object ob behalf
of its worker threads... if an application retains a reference they
can get out of sync. There is no mechanism for the application to tell
the container "hey, I need this session for quite a while into the
future" and so the container might not know it is "in use".

As for long-running HTTP requests, I believe Tomcat knows whether the
session is "currently" in use be a long-running request. But I'm not
sure about WebSocket... that may depend upon exactly how the
websocket-based service actually uses the session and/or obtains it.

For me, it doesn't matter: I have no session-persistence (except
across restarts), I have no clustering, and I have no websocket usage.
So at this point, this is an academic exercise for me.

> I'd say your safest bet is to validate the current
> implementation's behavior - e.g. your exact version of tomcat - and
> validate that it doesn't change in future versions. Based on Mark's
> comments it doesn't look like this is an area where tomcat's
> implementation would change soon. I'd just not expect it to be
> over-specified in the servlet spec.

Given all of the possible complications, here, I think you are
probably correct. It does present a problem for anyone who wants to do
things like ensure thread-safety between invocations of server-side
code using a shared session.

It seems I'm not the only one curious about this:

https://stackoverflow.com/questions/9802165/is-synchronization-within-an
- -httpsession-feasible

http://yet-another-dev.blogspot.com/2009/08/synchronizing-httpsession.ht
ml

> There's another argument that the servlet level might be the wrong
> level for creation of expensive objects, and that it's better
> delegated to the business layer. I can't judge that in your case,
> but quite often I've seen the servlet layer overly used for
> business problems. I don't like this a lot - your problem might be
> trivial to solve one or two layers down.

Speaking of "expensive" objects, we do have a "user" object in the
session. If the user isn't there, we throw all kinds of exceptions and
don't let "users" actually do anything except go to their login pages.

So I expect that I can (a) always rely on a "user" attribute being in
the session and (b) I can use that as my monitor.

As for where the "servlet level" or "business level" is the right
place to do these things... the lines are blurred when using e.g. a
web framework (e.g. Spring, Struts, etc.) since you are using objects
provided by the "servlet layer" (e.g. HttpSession) though you may be
using them through a particular interface -- like java.util.Map
instead of HttpSession.

In these cases, there *must* be a wrapper object and you may or may
not be using the same one across threads. So it seems like the object
stored *in* the session will pretty much always be a safer monitor
than pretty much anything else you could use.

The only reason this will work for me (100% bulletproof) is because
the "user" object is guaranteed to be present already. If I needed to
create a new object in the session to monitor, I'd need to either use
a HttpSessionListener to insert a "session monitor" into every session
- -- not a bad idea -- or use a complicated series of synchronized
blocks using other monitors to bootstrap things to be absolutely sure
I didn't create (and use) two separate monitor objects in two
different threads.

In this specific use-case I mentioned initially, a page is showing a
handful of <img> elements each of which make a request back to the
server for some dynamic data. All of that data benefits from a
session-backed cache and, because all of the requests come at the same
time from the client, there is great opportunity for race conditions.

Thanks,
- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQJRBAEBCAA7FiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlpg/3UdHGNocmlzQGNo
cmlzdG9waGVyc2NodWx0ei5uZXQACgkQHPApP6U8pFjFbBAAqntwxxdqI5IH6wbe
f6RcSzUhrd1Z3UuA/i4hTNyrFyArlcIVcbtG++BF8iLXATarKvuxO8lLGZU24b4X
R20TziHbPDd8rHHn8uH1FC27SCvAL4YmdayerbI/wvxoUEDfi0cf5B8LooQPi5aI
VJ7cEI6+PzttrFlWP1B7Vugpb/NRu4ax5UfpagqIpPGad++e3EbcNnbCEXxsxeTF
/inC0H7HutsHDmBp/9a8PjGdR7eVxxtb0kbRyx17hirBeGdPLc39Cb64u7m4ti5G
OnE5ISqIMSyd9a4hJ3LfKS2iG+18FFCV3Da453A3y7iI3zB9Yz+FjzCXYjIfAhvY
qSb9r74z/Tz+D1ISz67LJyFRxwj0SQI3stdjlpuuTQkKEIoBrusFLzCHKSxXUsPH
SR4nYt4/UvsZoQnrKkcfsEOglFNsWWsb89HXLR0ARfIsKkrVjya/QoF0TRVO1mfy
qypOHT/B8wmPhJKZ4smYpmoKPrf//INNfEK1BZJT9+mLNCFjl6NHptEJInmDAIqz
N/7IrFOqpsGEbJk6s7j7+xM6Ob54e3O9qjgVxkeo0aJEfZEoc6ndqIw92UFzs8dI
Nw77WEGD6JNo/WSP+F6a2GI4c899tHX9hh8+g6W5OLgb4YqHwfG/I0kQlIJLHFuQ
PNX+1/HMK/0/g5stfTraHoEXKu8=
=FzXm
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to