cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joerg Heinicke <joerg.heini...@gmx.de>
Subject Re: [IMP] synchronization on session object in Cocoon
Date Wed, 11 May 2005 15:22:13 GMT
Sylvain Wallez <sylvain <at> apache.org> writes:

> >I think I have found a more general problem with synchronization in Cocoon. I
> >tried to solve my problem with synchronization in flow script with an
> >intermediate object. This object handles the synchronized instantiation of my
> >component. Unfortunately I found out that "synchronized (session) { ... }"
> >still did not work - two requests of the same session run into that block at
> >the same time. I did some remote debugging. First I thought the reason is in
> >flow script as it also wraps the session, but it unwraps it later. The reason
> >is in HttpRequest class. Have a look at the code [1]:

> >As you can see on every request a new wrapper is instantiated which is really
> >bad. It is not possible to synchronize on Cocoon session objects.
> 
> Wow, very good point!
> 
> >What we probably need is a Map mapping the server sessions to the wrapper
> >objects.
> >  
> Or more simply we could store the wrapper in the session itself using an 
> attribute. That way it would be guaranteed to be created only once.

Yes, that's another possibility I also had in mind. But on the one hand this
smells a bit (storing a wrapper in the object that the wrapper wraps), on the
other hand you can not restrict access to it, so it can be manipulated from
somewhere else. But the Map solution can indeed be very resource consuming and a
bottle neck.

I have implemented the session attribute solution. Would be nice if you can
review it:

public Session getSession(boolean create) {
    // we must assure a 1:1-mapping of server session to cocoon session
    javax.servlet.http.HttpSession serverSession = this.req.getSession(create);
    if (serverSession != null) {
        synchronized (serverSession) {
            // retrieve existing wrapper
            this.session =
(HttpSession)serverSession.getAttribute(HTTP_SESSION);
            if (this.session == null) {
                // create wrapper
                this.session = new HttpSession(serverSession);
                serverSession.setAttribute(HTTP_SESSION, this.session);
            }
        }
    } else {
        // invalidate
        this.session = null;
    }
    return this.session;
}

An "update wrapper" (which was indeed an "update wrapped session") as in the old
implementation is IMO no longer necessary as only the server session holds the
wrapper - if it is a new server session we also must provide a new wrapper.

To avoid or at least recognize manipulation of the session attribute it is maybe
possible to let Cocoon's HttpSession implement HttpSessionAttributeListener and
to check on attributeReplaced(HttpSessionBindingEvent) [1] whether the wrapper
was replaced and not just removed on invalidation of the session. But first this
is no 100%-solution as someone could first remove and later set the attribute
and second it is again overhead (the event is triggered on every session
attribute add/remove/replace).
AFAICS the HTTPSessionBindingListener [2] does not help as there is no type of
HttpSessionBindingEvent, just the information that the wrapper was removed - and
this must happen when the session is invalidated.

WDYT?

Joerg

[1] http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/
HttpSessionAttributeListener.html
#attributeReplaced(javax.servlet.http.HttpSessionBindingEvent)

[2] http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/
HttpSessionBindingListener.html


Mime
View raw message