You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2006/05/27 02:16:53 UTC
svn commit: r409780 - in /beehive/trunk/netui:
src/pageflow/org/apache/beehive/netui/pageflow/
src/pageflow/org/apache/beehive/netui/pageflow/internal/
src/pageflow/org/apache/beehive/netui/pageflow/requeststate/
src/util/org/apache/beehive/netui/util/...
Author: ekoneil
Date: Fri May 26 17:16:53 2006
New Revision: 409780
URL: http://svn.apache.org/viewvc?rev=409780&view=rev
Log:
Changes to NetUI synchronization to facilitate synchronization on a session scoped lock. Before, locking was performed only on the HttpSession instance; in some circumstances, this isn't a safe operation because the HttpSession implementation can vary (even within application containers). This provides an HttpSessionListener that can be registered in web.xml in order to add a mutex object as a session attribute.
This can be retrieved by callers that need to synchronize some kind of change to the session. To enable this feature, simply add the following to a web application:
<listener>
<listener-class>org.apache.beehive.netui.pageflow.HttpSessionMutexListener</listener-class>
</listener>
The listener is optional; if not registered, the HttpSession will be used for synchronization.
The NameService and DeferredSessionStorageHandler were changed to synchronize on this session mutex.
BB: self
Test: NetUI pass
Added:
beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/HttpSessionMutexListener.java
Modified:
beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/DeferredSessionStorageHandler.java
beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/NameService.java
beehive/trunk/netui/src/util/org/apache/beehive/netui/util/internal/ServletUtils.java
beehive/trunk/netui/test/webapps/drt/web/WEB-INF/web.xml
Added: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/HttpSessionMutexListener.java
URL: http://svn.apache.org/viewvc/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/HttpSessionMutexListener.java?rev=409780&view=auto
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/HttpSessionMutexListener.java (added)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/HttpSessionMutexListener.java Fri May 26 17:16:53 2006
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.pageflow;
+
+import java.io.Serializable;
+import javax.servlet.http.HttpSessionListener;
+import javax.servlet.http.HttpSessionEvent;
+
+import org.apache.beehive.netui.util.internal.ServletUtils;
+
+/**
+ * <p>
+ * Class that implements an {@link HttpSessionListener} that adds a mutex object to the
+ * {@link javax.servlet.http.HttpSession}. This listener adds a session scoped attribute
+ * to the key {@link org.apache.beehive.netui.util.internal.ServletUtils#SESSION_MUTEX_ATTRIBUTE}
+ * that can be used as a safe reference to lock access to the session.
+ * </p>
+ * <p>
+ * To use this listener, it needs to be registered in <code>web.xml</code>.
+ * </p>
+ */
+public final class HttpSessionMutexListener
+ implements HttpSessionListener {
+
+ public void sessionCreated(HttpSessionEvent httpSessionEvent) {
+ httpSessionEvent.getSession().setAttribute(ServletUtils.SESSION_MUTEX_ATTRIBUTE, new Mutex());
+ }
+
+ public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
+ httpSessionEvent.getSession().removeAttribute(ServletUtils.SESSION_MUTEX_ATTRIBUTE);
+ }
+
+ /**
+ * An internal class that is instantiated per HttpSession to act as an object to use
+ * when locking an HttpSession.
+ */
+ private static final class Mutex implements Serializable {
+ }
+}
Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/DeferredSessionStorageHandler.java
URL: http://svn.apache.org/viewvc/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/DeferredSessionStorageHandler.java?rev=409780&r1=409779&r2=409780&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/DeferredSessionStorageHandler.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/DeferredSessionStorageHandler.java Fri May 26 17:16:53 2006
@@ -23,6 +23,7 @@
import org.apache.beehive.netui.pageflow.PageFlowController;
import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.util.internal.ServletUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
@@ -191,13 +192,15 @@
_log.debug("Applying changes for request " + request.getRequestURI() +
". Identity: " + System.identityHashCode(request));
+ Object sessionMutex = ServletUtils.getSessionMutex(session);
+
//
- // Synchronize on the HttpSession in order to make the operation of applying changes from a request into
+ // Synchronize on the session mutex in order to make the operation of applying changes from a request into
// the session atomic. Atomicity is needed in order to ensure that the attributes set in the session via
// "session.setAttribute(...)" are the same ones present when the "ensureFailover" call is made against the
// ServletContainerAdapter.
//
- synchronized(session) {
+ synchronized(sessionMutex) {
HashSet changedAttrs = getChangedAttributesList( request, false, true );
if ( changedAttrs != null )
@@ -342,7 +345,7 @@
// Start with the attribute names that are in the session.
if (session != null) {
for (Enumeration e = session.getAttributeNames(); e.hasMoreElements(); ) {
- attrNames.add((String) e.nextElement());
+ attrNames.add(e.nextElement());
}
}
Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/NameService.java
URL: http://svn.apache.org/viewvc/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/NameService.java?rev=409780&r1=409779&r2=409780&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/NameService.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/requeststate/NameService.java Fri May 26 17:16:53 2006
@@ -27,6 +27,8 @@
import java.util.Map;
import java.util.Set;
+import org.apache.beehive.netui.util.internal.ServletUtils;
+
/**
* This class implements a service that will name and track objects which implement the
* <code>INameable</code> interface. The typical use of this class is in the XmlHttpRequest
@@ -68,9 +70,10 @@
if (session == null)
throw new IllegalArgumentException("Session must not be null");
- // synchronize on the session so we only create a single NameService
- // within the session.
- synchronized (session) {
+ Object sessionMutex = ServletUtils.getSessionMutex(session);
+ // Synchronize on a session wide mutex to ensure that only a single NameService object is
+ // created within a specific user session
+ synchronized (sessionMutex) {
NameService nameService = (NameService) session.getAttribute(NAME_SERVICE);
if (nameService == null) {
nameService = new NameService();
Modified: beehive/trunk/netui/src/util/org/apache/beehive/netui/util/internal/ServletUtils.java
URL: http://svn.apache.org/viewvc/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/internal/ServletUtils.java?rev=409780&r1=409779&r2=409780&view=diff
==============================================================================
--- beehive/trunk/netui/src/util/org/apache/beehive/netui/util/internal/ServletUtils.java (original)
+++ beehive/trunk/netui/src/util/org/apache/beehive/netui/util/internal/ServletUtils.java Fri May 26 17:16:53 2006
@@ -27,8 +27,14 @@
import java.io.PrintStream;
import java.util.Enumeration;
-public class ServletUtils
-{
+import org.apache.beehive.netui.util.logging.Logger;
+
+public class ServletUtils {
+
+ private static final Logger LOG = Logger.getInstance(ServletUtils.class);
+
+ public static final String SESSION_MUTEX_ATTRIBUTE = ServletUtils.class.getName() + ".MUTEX";
+
/**
* Print parameters and attributes in the given request.
*
@@ -158,5 +164,32 @@
ServletException servletException = new ServletException(cause);
servletException.initCause(cause);
throw servletException;
+ }
+
+ /**
+ * Returns a mutex object for the given {@link HttpSession} that can be used to lock
+ * a given session. The semantics for locking on an HttpSession object are unspecified, and
+ * servlet containers are free to implement the HttpSession in such a way that acquiring a
+ * lock on the HttpSession itself is not safe. When used in conjunction with NetUI's
+ * HttpSessionMutexListener, this method provides a lock that is 100% safe to use across
+ * servlet containers. If the HttpSessionMutexListener is not registered in web.xml, the
+ * HttpSession itself is returned as the next best lock.
+ *
+ * @param httpSession the current session
+ * @return a mutex that can be used to serialize operations in a web application on the HttpSession
+ */
+ public static Object getSessionMutex(HttpSession httpSession) {
+ assert httpSession != null : "HttpSession must not be null";
+
+ Object mutex = httpSession.getAttribute(SESSION_MUTEX_ATTRIBUTE);
+ if(mutex == null)
+ mutex = httpSession;
+
+ assert mutex != null;
+
+ if(LOG.isDebugEnabled())
+ LOG.debug("Using session lock of type: " + mutex.getClass());
+
+ return mutex;
}
}
Modified: beehive/trunk/netui/test/webapps/drt/web/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/beehive/trunk/netui/test/webapps/drt/web/WEB-INF/web.xml?rev=409780&r1=409779&r2=409780&view=diff
==============================================================================
--- beehive/trunk/netui/test/webapps/drt/web/WEB-INF/web.xml (original)
+++ beehive/trunk/netui/test/webapps/drt/web/WEB-INF/web.xml Fri May 26 17:16:53 2006
@@ -10,11 +10,14 @@
<param-name>jpf-secure-forwards</param-name>
<param-value>true</param-value>
</context-param>
-<!--
+
<listener>
<listener-class>org.apache.beehive.netui.pageflow.PageFlowContextListener</listener-class>
</listener>
--->
+
+ <listener>
+ <listener-class>org.apache.beehive.netui.pageflow.HttpSessionMutexListener</listener-class>
+ </listener>
<!-- Test Recorder Filter -->
<filter>