[jsr369-experts] Re: Data Structures and Session Replication

From: Mark Thomas <markt_at_apache.org>
Date: Tue, 10 Feb 2015 14:45:02 +0000

On 09/02/2015 13:42, Edward Burns wrote:
> My pal Mark Struberg sent this to the users list moments ago and I feel
> it is important to bring to the formal list. We've faced this problem
> in JSF and have a brute force solution, but would welcome something
> better. I don't have a good suggestion, though!
>>>>>> On Mon, 9 Feb 2015 13:06:14 +0000 (UTC), Mark Struberg <struberg_at_yahoo.de> said:
> MS> I came across this a few times already and I think it's finally time
> MS> to resolve the following underspecified behaviour.
> MS> Some servlet container support so called 'delta-replication'. That
> MS> means they only transfer session attributes to another cluster node
> MS> if they got changed in a request (instead of always transferring ALL
> MS> the session content to the other node/nodes). This is a nice feature
> MS> as it sometimes helps to heavily reduce the network traffic.
> MS> The underspecified area is how to detect WHAT to transfer.
> MS> Tomcat e.g. only transfers attributes which got set via a
> MS> Session#setAttribute() in the current request. Other containers have
> MS> since mimicked this behaviour but still there are subtle
> MS> differences.
> MS> The tricky point is how to tell the servlet container that some
> MS> attributes needs to get transferred despite it's instance reference
> MS> in the Sessions attribute map did not change at all.
> MS> E.g. consider a
> MS> List<PurchaseItem> shoppingCart = new ArrayList<>();
> MS> session.setAttribute("shoppingcart", shoppingCart);
> MS> Now even if you change the content of the shoppingCart in subsequent
> MS> requests the reference itself does NOT change. To tell Tomcat that
> MS> this attribute still needs to be transferred in the
> MS> delta-replication you have to invoke session.setAttribute again in
> MS> those requests where you changed it's content.
> MS> I've seen this working pretty well but there are quite a few things
> MS> which can get wrong.
> MS> E.g. Tomcat detects that setAttribute replaces 'itself' and thus
> MS> suppresses the attribute 'destroyal'. Other containers just send out
> MS> all the events like HttpSessionBindingListener#valueUnbound, etc.
> JSF has an option com.sun.faces.enableAgressiveSessionDirtying (sic)
> that does this for all JSF session scoped managed beans.
> MS> At the end I was not able to get delta-replication running portably
> MS> across servers and had to switch the feature off in a few of them.
> MS> I'm not quite sure if delta-replication should get mentioned in the
> MS> spec at all but maybe it's worth to at least unify the 'destroyal'
> MS> of attributes in such a case.
> MS> There are a few more subtle differences and maybe other users also
> MS> have some quirks mode/hack/workaround to share.
> This is an ancient problem, I would expect others have solved it
> already. Even though the set of solutions may include it, I think we
> should not try to come up with some "automatic" solution. Rather,
> consider if we can create an API for developers to call that advises the
> Servlet that a particular entry in the session should be replicated.

I've seen this requested many times to. There is an outstanding
enhancement request for this in Tomcat. How about:

HttpSession.markAsDirty(String attributeName)

We should clarify in the spec/Javadoc whether this means that the
container should act on this immediately (i.e. changes made in the
current request after this is called are not replicated) or if the
container should act on this when the request completes. My preference
is for the latter.