-----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