BaseOptimizedSessionPersistedObject does not work correctly with Tomcat & Jetty
-------------------------------------------------------------------------------

                 Key: TAP5-834
                 URL: https://issues.apache.org/jira/browse/TAP5-834
             Project: Tapestry 5
          Issue Type: Bug
          Components: tapestry-core
    Affects Versions: 5.0.18, 5.1.0.5, 5.1.0.4, 5.1.0.3, 5.1.0.2, 5.1.0.1, 
5.1.0.0
            Reporter: Andy Blower
            Priority: Critical


OptimizedSessionPersistedObject's suggestion for implementing 
isSessionPersistedObjectDirty(), as used by 
BaseOptimizedSessionPersistedObject, does not work correctly with Tomcat & 
Jetty. (and quite possibly other servlet containers too, but we only use Jetty 
& Tomcat so have only confirmed it with them)

OptimizedSessionPersistedObject model relies on the servlet container session 
object triggering a HttpSessionBindingEvent when an object is re-stored in the 
session to reset the dirty flag. I've only looked at the source of Tomcat 5.5 
and 6 but when an object is replaced in the session using setAttribute() the 
new object and the existing object are compared by reference only, if they both 
refer to the same object then no HttpSessionBindingEvent is triggered.

>From Tomcat StandardSession.java:

        // Call the valueBound() method if necessary
        if (notify && value instanceof HttpSessionBindingListener) {
            // Don't call any notification if replacing with the same value
            Object oldValue = attributes.get(name);
            if (value != oldValue) {
                event = new HttpSessionBindingEvent(getSession(), name, value);
                try {
                    ((HttpSessionBindingListener) value).valueBound(event);
                } catch (Throwable t){
                    manager.getContainer().getLogger().error
                    (sm.getString("standardSession.bindingEvent"), t); 
                }
            }
        }

So, using OptimizedSessionPersistedObject, there is currently no way of setting 
the dirty flag to false after the object has been saved in the session - hence 
we are propagating all of the SSOs across the cluster all of the time because 
the dirty flag stays set to true.

I think there are two possible solutions to this issue - I prefer the first by 
a large margin, but both modify the SessionImpl.restoreDirtyObjects() method.

1) Add a new method to OptimizedSessionPersistedObject interface to reset the 
dirty flag, and a corresponding method in SessionPersistedObjectAnalyzer - 
implementing them as appropriate, then call the new reset method after setting 
the session attribute in SessionImpl.restoreDirtyObjects().

2) Remove the session attribute before adding it in 
SessionImpl.restoreDirtyObjects(). Although I have a worry that this may 
potentially cause hard to find concurrency problems.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to