On Mon, Dec 11, 2017 at 3:01 PM, Eric B <ebenzacar(a)gmail.com> wrote:
Hi Stuart,
Thanks for the reply. A few followup questions if you don't mind.
>> 1) on any specific node, request.getSession() returns a different object
>> for each request. The sessionId() remains the same, but the actual object
>> ID changes. This implies that it is a different representation of the
>> session object.
>>
>
> Undertow returns a different facade for each request. Undertow uses its
> internal representation of a session (io.undertow.server.session.Session)
> that is stored in the session manager, and wraps a facade around it
> (io.undertow.servlet.spec.HttpSessionImpl) that implements Servlet
> semantics.
>
That's what I had assumed as well, based on the behaviour I had noticed.
Thanks for confirming.
>
>
>>
>> 2) if I persist a local copy of the HttpSession object between requests
>> (ex: in a static map) and invalidate the session using the persisted
>> object, my request.getSession() object is not updated (ex: the invalid flag
>> is still set to false), but the session is dead. Trying to call
>> request.getSession().invalidate() throws IllegalStateException as do
>> calls to request.getSession().set/getAttribute()
>>
>
> I guess this could be considered a bug in that isNew will not throw an
> IllegalStateException, which is the only place that the invalid flag is
> used without also consulting the underlying session, but you sound as if
> you expect the session to still work after it has been invalidated?
>
No - quite the opposite actually. I'm expecting that all session objects
to react the same after it has been invalidated. If I use one of the
facades from a prior request to invalidate the session, I would expect that
every facade would respect the same state. For instance, if I do the
following:
Request 1:
// store a copy of the session object to be available in a later request
static Session cachedSessionObj = request.getSession();
Request 2:
// invalidate the session from the cached object
cachedSessoinObject.invalidate();
// get a new session
Session newSession = request.getSession();
I would expect that cachedSessionObj.getId() != newSessoin.getId().
However, the request.getSession() doesn't get a new session object.
Rather it still returns the old (now invalidated) session object. So any
logic that is dependent on having a fresh session object fails (since the
session object is returned is actually the invalidated session).
Once a session has been assigned to the request it does not change. This is
a bit of a grey area.
> There is no requirement that the same session is represented by a single
> java object, and especially it in a distributed environment this is not
> possible. Even though we could keep the same facade around for all requests
> this can encourage people to write apps that rely on this behaviour, and
> also increases the likelihood that the facade will become tenured and
> require a full GC to be reclaimed.
>
Understood.
>
>> 3) over time, my JVM will actually crash with an
>> EXCEPTION_ACCESS_VIOLATION in a GC process. This always seems to correlate
>> with a thread that is trying to do some session invalidation via the
>> persisted session copy.
>>
>
> This is a JVM bug. Which JVM are you using?
>
I'm running Oracle Hotspot Java 8x64 on a Windows platform (server 2016).
I've tried with both patch 131 and 151, and both exhibit the same
behaviour.
I would report it to Oracle.
To implement this I would remove the WeakReference which will not work
> with Undertow's session management strategy, and instead register a
> listener to remove the session from the local map when it is invalidated.
> If you really want to access the underlying Undertow session you can
> call io.undertow.servlet.spec.HttpSessionImpl#getSession() to return the
> Underlying Undertow session, although it should not be necessary.
>
I've already removed the WeakReference as soon as I noticed that the
session facade returned by Undertow changed at each request. I am using a
session listener to remove it from the local map when it is invalidated,
but I need an ability for an JMS listener to be able to invalidate a
session object based on an id it receives.
How can I access Undertow's SessionManager from within my application? Is
there any way I can retrieve it from the CDI? I tried adding
the io.undertow.core module to my jboss-deployment-structure.xml, but yet
I can't access it via injection or via: CDI.current().
getBeanManager().getBeans(SessionManager.class); in both cases it is
unable to find the SessionManager class. Is there some other way I can
access it/retrieve it from within my application?
You can
do io.undertow.servlet.spec.ServletContextImpl#getSession(java.lang.String)
to get an arbitrary session.
If you want the actual SessionManager you would need to
call io.undertow.servlet.spec.ServletContextImpl#getDeployment().getSessionManager().
Stuart
Thanks,
Eric
> Is anyone able to explain this behaviour? Why is the session object
>> always different between requests? Shouldn't it be the same request? What
>> is Undertow doing with the session objects between requests? Is the
>> Undertow object being passivated in some way and my attempt to invalidate
>> if from within my cached version causing this kind of access violation? Is
>> my cached object referencing memory that has been cleared by the GC (ex:
>> does the request.getSession() object only a WeakReference to the actual
>> Undertow object)?
>>
>>
>> Finally, what would the recommended approach be to doing something like
>> this? Using a distributed web-cache is unfortunately not an option at the
>> moment. So give that, is there some way to access the Undertow session
>> manager directly?
>>
>> Thanks for any insight. I thought we had a functional solution but in
>> production (under real load), the intermittent JVM crashes are telling me
>> that our solution is broken.
>>
>> Eric
>>
>> _______________________________________________
>> wildfly-dev mailing list
>> wildfly-dev(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>
>
>