[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [servlet-dev] WebSocket and HttpSession
|
On 12/06/2023 15:27, Greg Wilkins wrote:
Mark,
Something like that might be possible, but I don't really don't like
many aspects of this proposal.
Fair enough. Happy to keep discussing until we find a consensus. My aim
is to try and find a solution to the problem.
The Session object returned from request.getSession was never intended
to be used beyond the scope of the request lifecycle.
I don't think the spec makes that clear one way or the other. I can see
how it could be read that way but I can also see the counter argument.
Putting
startAccess/endAccess on the session API would be problematic for
several of our implementations as we really don't like objects that have
been passivated suddenly becoming active again. Doing so is just asking
for races! Nor are all our implementations intended to be shared
between multiple requests, let alone other threads. Thus I think the API
needs to be on something else other than the session.
I understand the points you are making. I worry slightly that we are
constraining the solution space to suit the current implementations of
one container but lets see if using some other object could work.
Applications can call unmatched endAccess.
Fixing that was a detail I was intending to leave until later if the
general approach was agreeable.
It would be far better to
have something like access(Consumer<Session>) that could be called with
the activated session. Hmmm but that is blocking. Maybe something like
access(BiConsumer<Session, Runnable>, with the Runnable being the end event.
I like the access(Consumer<Session>) suggestion.
Session access is currently blocking so I'm not overly concerned about
blocking vs non-blocking. In what scenarios do you see non-blocking
being useful here?
All in all, session semantics are poorly defined enough for incoming
HTTP requests, without adding this complication.
Hopefully we can improve the definition of the semantics. I do think
defining this behaviour it terms of an HTTP request - even if it isn't -
would aid simplicity. Something like:
For the purposes of session access, validity, passivation, activation,
etc. the actions taken during this method should be considered
equivalent to an HTTP request starting, performing the actions and then
finishing. (I'm sure that wording can be improved.)
Actually that might be a better solution: let websocket use actual HTTP
requests sent over a local connector to hit the application normally, so
all normal session semantics will apply. I.e. we should provide a
simple way to create locally HTTP invocations.
That should be largely doable with the existing API. I don't really like
the idea of processing a full HTTP request just to update the session.
It seems rather inefficient.
Going back to your "do this via some other object" suggestion, did you
have anything in mind?
If we are going to add a access(Consumer<Session>) method then it needs
to be added to an object where the current session is implied or we need
to provide the session ID as well.
Currently the WebSocket HandshakeRequest doesn't have access to much.
The HttpSession looks like the most likely candidate. Something like
Xxxxxxx HttpSession.getXxxxxxx()
where new class Xxxxxxx has the method
Xxxxxxx.access(Consumer<Session>)
(I'm using Xxxxxxx as I can't think of a good name right now.)
Mark
On Mon, 12 Jun 2023 at 12:38, Mark Thomas <markt@xxxxxxxxxx
<mailto:markt@xxxxxxxxxx>> wrote:
On 09/06/2023 18:34, Greg Wilkins wrote:
> On Thu, 8 Jun 2023 at 17:58, Mark Thomas <markt@xxxxxxxxxx
<mailto:markt@xxxxxxxxxx>
> <mailto:markt@xxxxxxxxxx <mailto:markt@xxxxxxxxxx>>> wrote:
>
>
> My proposal is to add the following method to HttpSession:
>
> public void access()
>
>
> That may not be sufficient, because there are two states of a
session
> that websockets needs to avoid: invalidation and passivation!
I agree the proposal will not be sufficient for all scenarios. However,
if it is sufficient for some scenarios then I think it is worth
considering.
> Having an access method could well prevent invalidation due to an
idle
> timeout, but it will stop passivation if that is configured on the
> container. Typically a session is passivated some time interval
> after the active request count goes to 0. Often this timeout is
much
> shorter than the idle timeout and we have some deployments that
have a
> zero passivation timeout, so the session is passivated as soon as
the
> last request exits the servlet container.
>
> A passivated session will not be available to be accessed by a
websocket
> endpoint.
>
> There are further complications with websocket endpoint accessing
> sessions. For example, what is the dirty semantic? i.e. if the
> websocket endpoint modifies the session, then when are those changes
> persisted/distributed in the cluster? We HTTP request, we have
commit
> and complete events on which we can flush a dirty session.
>
> Session semantics is really poorly defined and barely sufficient for
> purpose for HTTP requests/responses. I've very dubious that it's
> semantics can be extended to websockets without creating some more
> horrid corner cases. Very careful thought is needed and I do
not think
> there are any simple solutions.
I agree a complete solution may not be simple. I'm happy to look at the
wider problem (we have a number of open issues against the Servlet spec
for those) but I'd also like to make progress on this WebSocket
issue if
we can.
I'm not sure I like it but something that could work would be two
methods:
public void startAccess()
public void endAccess()
These would be intended for non-HTTP based application components (e.g.
WebSocket) to work with the session. Roughly (details to be fleshed out
if the principal is acceptable):
- startAccess()
- container treats it as the start of an HTTP request
- active request count is incremented
- last access time is updated
- endAccess()
- container treats it as the start of an HTTP request
- active request count is incremented
- changes to the session are distributed/persisted
The idea being that if WebSocket (or anything else) wants to update the
session it needs to do so between startAccess() and endAccess().
Mark
_______________________________________________
servlet-dev mailing list
servlet-dev@xxxxxxxxxxx <mailto:servlet-dev@xxxxxxxxxxx>
To unsubscribe from this list, visit
https://www.eclipse.org/mailman/listinfo/servlet-dev
<https://www.eclipse.org/mailman/listinfo/servlet-dev>
--
Greg Wilkins <gregw@xxxxxxxxxxx <mailto:gregw@xxxxxxxxxxx>> CTO
http://webtide.com <http://webtide.com>
_______________________________________________
servlet-dev mailing list
servlet-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/servlet-dev