[
https://issues.apache.org/jira/browse/TAP5-1355?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12936116#action_12936116
]
Josh Canfield commented on TAP5-1355:
-------------------------------------
Hi Andy.
Sorry, I jumped to solving the immediate problem and didn't step back to
consider the base problem that was originally being solved. The problem seems
to be that Tapestry is depending on HttpSessionBindingListener in order to
manage session attribute lifecycle, and that the behavior is container
specific. I looked at the Jetty code and it uses .equals, but Tomcat uses != to
determine whether to call the valueBound method.
The servlet spec is not clear about what the right behavior is for the
container. I was surprised that the spec is actually self contradictory about
how the method was even supposed to be called. For instance, in the 2.4 spec
SRV.7.4 "The valueBound method must be called before the object is made
available via the getAttribute method of the HttpSession interface." and then
in SRV.15.1.7, the javadoc for HttpSession it says "Notifications are sent
after the binding methods complete." Both Tomcat and Jetty seem take the
approached defined in the HttpSession docs (maybe I'm reading something wrong
here.) This means that in a situation where you are accessing the object in a
multi-threaded manner you could get the object from the session before your
valueBound method has even run. Threading issues have been left up to the
developer.
The biggest hole though, there is no specification as far as I can find as to
what it means to "bind" an object to the session. Jetty will call valueBound if
the .equals says it's different, Tomcat only if the object has changed (you
only bind an object to the session once). Since we have two containers that
behave differently we can only imagine that other containers will take
alternating approaches.
To sum up; the prevailing wisdom seems to be that after changing the value
within a session attribute that calling session.setAttribute() is enough to get
clustered session attribute replicated. Having spent some time with this code I
think the dependency on HttpSessionBindingListener should be dropped and
Tapestry should go with Andy's number two solution. Keeping the dirty/clean
cycle within Tapestry's code.
> Threading issue with SessionStateObjects
> ----------------------------------------
>
> Key: TAP5-1355
> URL: https://issues.apache.org/jira/browse/TAP5-1355
> Project: Tapestry 5
> Issue Type: Bug
> Components: tapestry-core
> Affects Versions: 5.2.4
> Reporter: Moritz Gmelin
> Attachments: Screenshot.png.jpg, taptest.tgz
>
>
> When a page request consists of multiple HTTP request (e.g. page and some
> dynamically generated images) and all those requests access a
> SessionStateObject, it happens that a new session (with an empty SSO) is
> created for some of the request threads.
> I was able to create a very simple example to recreate that problem:
> -A simple page that displays 20 dynamically generated images in a loop.
> -In the page, a SSO, holding a number value is initialized to a random
> number.
> -Each of the dynamic images read that number and draws it.
> -Make sure that a HTTP-Request is made for every image on the page (by
> adding some random number to the event link)
> The effect that you'll see after some reloads of the page (maybe you need to
> reload 30 times) is that some images will draw 0 as SSO value instead of the
> number set in the page @BeginRender method. Those fields will be marked in
> red in the demo so you can quickly see them.
> I definitely beleive that tapestry should take care of this. It is a use case
> for SSOs that is probably too common to ignore.
> Why can't this be automatically integrated into the ApplicationStateManager?
>
> The demo has been deployed here
> http://www.avetana.de/taptest/
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.