RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

View: New views
4 Messages — Rating Filter:   Alert me  

Parent Message unknown RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

by Michael Rimov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
[5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

Woo hoo! :)

 

Very cool Paul!

                                                                                                                                                                -Mike

 

 

From: paul@... [mailto:paul@...]
Sent: Monday, June 08, 2009 10:46 PM
To: scm@...
Subject: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

 

Diff

Modified: java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/appengine-web.xml (5425 => 5426)

 

--- java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/appengine-web.xml        2009-06-08 17:48:15 UTC (rev 5425)

+++ java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/appengine-web.xml        2009-06-09 05:46:01 UTC (rev 5426)

@@ -1,7 +1,7 @@

 <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

   <application>ham-scratch</application>

-  <sessions-enabled>true</sessions-enabled>

-  <version>101</version>

+  <!--sessions-enabled>true</sessions-enabled-->

+  <version>103</version>

   <static-files>

       <include path="images/*" />

       <include path="js/*" />

Modified: java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/web.xml (5425 => 5426)

 

--- java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/web.xml  2009-06-08 17:48:15 UTC (rev 5425)

+++ java/2.x/trunk/web/examples/ajax-email/src/main/webapp/WEB-INF/web.xml  2009-06-09 05:46:01 UTC (rev 5426)

@@ -11,6 +11,11 @@

         <param-value>org.picocontainer.web.sample.ajaxemail.AjaxEmailWebappComposer</param-value>

     </context-param>

 

+    <context-param>

+        <param-name>stateless-webapp</param-name>

+        <param-value>true</param-`value>

+    </context-param>

+

     <filter>

         <filter-name>picoFilter</filter-name>

         <filter-class>org.picocontainer.web.remoting.AbstractPicoWebRemotingServlet$ServletFilter</filter-class>

Modified: java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java (5425 => 5426)

 

--- java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java  2009-06-08 17:48:15 UTC (rev 5425)

+++ java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java  2009-06-09 05:46:01 UTC (rev 5426)

@@ -34,12 +34,15 @@

 public abstract class PicoServletContainerFilter implements Filter, Serializable {

 

     private boolean exposeServletInfrastructure;

+    private boolean isStateless;

 

     public void init(FilterConfig filterConfig) throws ServletException {

         ServletContext context = filterConfig.getServletContext();

         ScopedContainers scopedContainers = getScopedContainers(context);

         setAppContainer(scopedContainers.getApplicationContainer());

 

+        isStateless = Boolean.parseBoolean(context.getInitParameter(PicoServletContainerListener.STATELESS_WEBAPP));

+

         String exposeServletInfrastructureString = filterConfig.getInitParameter("exposeServletInfrastructure");

         if (exposeServletInfrastructureString == null || Boolean.parseBoolean(exposeServletInfrastructureString)) {

             exposeServletInfrastructure = true;

@@ -72,7 +75,8 @@

 

     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {

 

-        HttpSession sess = ((HttpServletRequest) req).getSession();

+        HttpServletRequest servletRequest = (HttpServletRequest) req;

+        HttpSession sess = servletRequest.getSession();

         if (exposeServletInfrastructure) {

             currentSession.set(sess);

             currentRequest.set(req);

@@ -81,25 +85,31 @@

 

         ScopedContainers scopedContainers = getScopedContainers(sess.getServletContext());

 

-        SessionStoreHolder ssh = (SessionStoreHolder) getSessionAttribute(sess, SessionStoreHolder.class.getName());

-        if (ssh == null) {

-            if (scopedContainers.getSessionContainer().getComponentAdapters().size() > 0) {

-                throw new PicoContainerWebException("Session not setup correctly.  There are components registered " +

-                        "at the session level, but no working container to host them");

+        SessionStoreHolder ssh = null;

+        if (!isStateless) {

+

+            ssh = (SessionStoreHolder) sess.getAttribute(SessionStoreHolder.class.getName());

+            if (ssh == null) {

+                if (scopedContainers.getSessionContainer().getComponentAdapters().size() > 0) {

+                    throw new PicoContainerWebException("Session not setup correctly.  There are components registered " +

+                            "at the session level, but no working container to host them");

+                }

+                ssh = new SessionStoreHolder(scopedContainers.getSessionStoring().getCacheForThread(), new DefaultLifecycleState());

             }

-            ssh = new SessionStoreHolder(scopedContainers.getSessionStoring().getCacheForThread(), new DefaultLifecycleState());

-        }

 

-        scopedContainers.getSessionStoring().putCacheForThread(ssh.getStoreWrapper());

-        scopedContainers.getSessionState().putLifecycleStateModelForThread(ssh.getLifecycleState());

+            scopedContainers.getSessionStoring().putCacheForThread(ssh.getStoreWrapper());

+            scopedContainers.getSessionState().putLifecycleStateModelForThread(ssh.getLifecycleState());

 

+        }

         scopedContainers.getRequestStoring().resetCacheForThread();

         scopedContainers.getRequestState().resetStateModelForThread();

 

         scopedContainers.getRequestContainer().start();

 

         setAppContainer(scopedContainers.getApplicationContainer());

-        setSessionContainer(scopedContainers.getSessionContainer());

+        if (!isStateless) {

+            setSessionContainer(scopedContainers.getSessionContainer());

+        }

         setRequestContainer(scopedContainers.getRequestContainer());

 

         containersSetupForRequest(scopedContainers.getApplicationContainer(), scopedContainers.getSessionContainer(), scopedContainers.getRequestContainer(), req, resp);

@@ -107,19 +117,25 @@

         filterChain.doFilter(req, resp);

 

         setAppContainer(null);

-        setSessionContainer(null);

+        if (!isStateless) {

+            setSessionContainer(null);

+        }

         setRequestContainer(null);

 

         scopedContainers.getRequestContainer().stop();

         scopedContainers.getRequestContainer().dispose();

 

-        sess.setAttribute(SessionStoreHolder.class.getName(), ssh);

-

+        if (!isStateless) {

+            System.out.println("********** Write to Session *******");

+            sess.setAttribute(SessionStoreHolder.class.getName(), ssh);

+        }

         scopedContainers.getRequestStoring().invalidateCacheForThread();

         scopedContainers.getRequestState().invalidateStateModelForThread();

 

-        scopedContainers.getSessionStoring().invalidateCacheForThread();

-        scopedContainers.getSessionState().invalidateStateModelForThread();

+        if (!isStateless) {

+            scopedContainers.getSessionStoring().invalidateCacheForThread();

+            scopedContainers.getSessionState().invalidateStateModelForThread();

+        }

 

         if (exposeServletInfrastructure) {

             currentSession.set(null);

@@ -129,10 +145,6 @@

 

     }

 

-    private Object getSessionAttribute(HttpSession sess, String name) {

-        return sess.getAttribute(name);

-    }

-

     protected void containersSetupForRequest(MutablePicoContainer appcontainer, MutablePicoContainer sessionContainer,

                                              MutablePicoContainer requestContainer, ServletRequest req, ServletResponse resp) {

     }

Modified: java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerListener.java (5425 => 5426)

 

--- java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerListener.java       2009-06-08 17:48:15 UTC (rev 5425)

+++ java/2.x/trunk/web/web-core/src/java/org/picocontainer/web/PicoServletContainerListener.java       2009-06-09 05:46:01 UTC (rev 5426)

@@ -8,10 +8,6 @@

 package org.picocontainer.web;

 

 import java.io.Serializable;

-import java.lang.annotation.Annotation;

-import java.lang.reflect.Type;

-import java.util.Collection;

-import java.util.List;

 

 import javax.servlet.ServletContext;

 import javax.servlet.ServletContextEvent;

@@ -26,14 +22,10 @@

 import org.picocontainer.BehaviorFactory;

 import org.picocontainer.LifecycleStrategy;

 import org.picocontainer.ComponentMonitor;

-import org.picocontainer.ComponentAdapter;

-import org.picocontainer.NameBinding;

-import org.picocontainer.PicoException;

-import org.picocontainer.injectors.ConstructorInjection;

+import org.picocontainer.MutablePicoContainer;

 import org.picocontainer.monitors.NullComponentMonitor;

 import org.picocontainer.lifecycle.StartableLifecycleStrategy;

 import org.picocontainer.containers.EmptyPicoContainer;

-import org.picocontainer.containers.AbstractDelegatingPicoContainer;

 import org.picocontainer.behaviors.Storing;

 import org.picocontainer.behaviors.Guarding;

 import org.picocontainer.behaviors.Caching;

@@ -78,7 +70,10 @@

 public class PicoServletContainerListener implements ServletContextListener, HttpSessionListener, Serializable {

 

     public static final String WEBAPP_COMPOSER_CLASS = "webapp-composer-class";

-   

+

+    public static final String STATELESS_WEBAPP = "stateless-webapp";

+

+    private boolean isStateless;

     /**

      * Default constructor used in webapp containers

      */

@@ -89,10 +84,14 @@

 

         ServletContext context = event.getServletContext();

 

+        isStateless = Boolean.parseBoolean(context.getInitParameter(STATELESS_WEBAPP));

+

         ScopedContainers scopedContainers = makeScopedContainers();

 

         scopedContainers.getApplicationContainer().setName("application");

-        scopedContainers.getSessionContainer().setName("session");

+        if (!isStateless) {

+            scopedContainers.getSessionContainer().setName("session");

+        }

         scopedContainers.getRequestContainer().setName("request");

 

         compose(loadComposer(context), context, scopedContainers);

@@ -118,16 +117,30 @@

      * @return an instance of ScopedContainers

      */

     protected ScopedContainers makeScopedContainers() {

+        return makeScopedContainers(false);

+    }

+    protected ScopedContainers makeScopedContainers(boolean stateless) {

         DefaultPicoContainer appCtnr = new DefaultPicoContainer(new Guarding().wrap(new Caching()), makeLifecycleStrategy(), makeParentContainer(), makeAppComponentMonitor());

-        Storing sessStoring = new Storing();

-        DefaultPicoContainer sessCtnr = new DefaultPicoContainer(new Guarding().wrap(sessStoring), makeLifecycleStrategy(), appCtnr, makeSessionComponentMonitor());

+        DefaultPicoContainer sessCtnr;

+        PicoContainer parentOfRequestContainer;

+        ThreadLocalLifecycleState sessionState;

+        Storing sessStoring;

+        if (stateless) {

+            sessionState = null;

+            sessStoring = null;

+            sessCtnr = null;

+            parentOfRequestContainer = appCtnr;

+        } else {

+            sessionState = new ThreadLocalLifecycleState();

+            sessStoring = new Storing();

+            sessCtnr = new DefaultPicoContainer(new Guarding().wrap(sessStoring), makeLifecycleStrategy(), appCtnr, makeSessionComponentMonitor());

+            sessCtnr.setLifecycleState(sessionState);

+            parentOfRequestContainer = sessCtnr;

+        }

         Storing reqStoring = new Storing();

         DefaultPicoContainer reqCtnr = new DefaultPicoContainer(new Guarding().wrap(addRequestBehaviors(reqStoring)), makeLifecycleStrategy(), sessCtnr, makeRequestComponentMonitor());

-        ThreadLocalLifecycleState sessionState = new ThreadLocalLifecycleState();

         ThreadLocalLifecycleState requestState = new ThreadLocalLifecycleState();

-        sessCtnr.setLifecycleState(sessionState);

         reqCtnr.setLifecycleState(requestState);

-

         return new ScopedContainers(appCtnr, sessCtnr, reqCtnr, sessStoring, reqStoring, sessionState, requestState);

     }

 

@@ -180,7 +193,9 @@

 

     protected void compose(WebappComposer composer, ServletContext context, ScopedContainers scopedContainers) {

         composer.composeApplication(scopedContainers.getApplicationContainer(), context);

-        composer.composeSession(scopedContainers.getSessionContainer());

+        if (!isStateless) {

+            composer.composeSession(scopedContainers.getSessionContainer());

+        }

         composer.composeRequest(scopedContainers.getRequestContainer());

     }

 

@@ -195,33 +210,29 @@

     }

 

     public void sessionCreated(HttpSessionEvent event) {

-

-        HttpSession session = event.getSession();

-        ScopedContainers scopedContainers = getScopedContainers(session.getServletContext());

-

-        SessionStoreHolder ssh = new SessionStoreHolder(scopedContainers.getSessionStoring().resetCacheForThread(), scopedContainers.getSessionState().resetStateModelForThread());

-

-        scopedContainers.getSessionContainer().start();

-        session.setAttribute(SessionStoreHolder.class.getName(), ssh);

-

+        if (!isStateless) {

+            HttpSession session = event.getSession();

+            ScopedContainers scopedContainers = getScopedContainers(session.getServletContext());

+            SessionStoreHolder ssh = new SessionStoreHolder(scopedContainers.getSessionStoring().resetCacheForThread(), scopedContainers.getSessionState().resetStateModelForThread());

+            scopedContainers.getSessionContainer().start();

+            session.setAttribute(SessionStoreHolder.class.getName(), ssh);

+        }

     }

 

     public void sessionDestroyed(HttpSessionEvent event) {

-        HttpSession session = event.getSession();

-        ScopedContainers scopedContainers = getScopedContainers(session.getServletContext());

-

-        SessionStoreHolder ssh = (SessionStoreHolder) session.getAttribute(SessionStoreHolder.class.getName());

-

-        scopedContainers.getSessionStoring().putCacheForThread(ssh.getStoreWrapper());

-        scopedContainers.getSessionState().putLifecycleStateModelForThread(ssh.getLifecycleState());

-

-        scopedContainers.getSessionContainer().stop();

-        scopedContainers.getSessionContainer().dispose();

-

-        scopedContainers.getSessionStoring().invalidateCacheForThread();

-        scopedContainers.getSessionState().invalidateStateModelForThread();

-       

-        session.setAttribute(SessionStoreHolder.class.getName(), null);

+        if (!isStateless) {

+            HttpSession session = event.getSession();

+            ScopedContainers scopedContainers = getScopedContainers(session.getServletContext());

+            MutablePicoContainer sessionCtr = scopedContainers.getSessionContainer();

+            SessionStoreHolder ssh = (SessionStoreHolder) session.getAttribute(SessionStoreHolder.class.getName());

+            scopedContainers.getSessionStoring().putCacheForThread(ssh.getStoreWrapper());

+            scopedContainers.getSessionState().putLifecycleStateModelForThread(ssh.getLifecycleState());

+            sessionCtr.stop();

+            sessionCtr.dispose();

+            scopedContainers.getSessionStoring().invalidateCacheForThread();

+            scopedContainers.getSessionState().invalidateStateModelForThread();

+            session.setAttribute(SessionStoreHolder.class.getName(), null);

+        }

     }

 

 }

Modified: java/2.x/trunk/web/web-remoting/src/java/org/picocontainer/web/remoting/AbstractPicoWebRemotingServlet.java (5425 => 5426)

 

--- java/2.x/trunk/web/web-remoting/src/java/org/picocontainer/web/remoting/AbstractPicoWebRemotingServlet.java        2009-06-08 17:48:15 UTC (rev 5425)

+++ java/2.x/trunk/web/web-remoting/src/java/org/picocontainer/web/remoting/AbstractPicoWebRemotingServlet.java        2009-06-09 05:46:01 UTC (rev 5426)

@@ -270,7 +270,10 @@

 

     private void publishAdapters() {

         pwr.publishAdapters(currentRequestContainer.get().getComponentAdapters(), REQUEST_SCOPE);

-        pwr.publishAdapters(currentSessionContainer.get().getComponentAdapters(), SESSION_SCOPE);

+        MutablePicoContainer sessionContainer = currentSessionContainer.get();

+        if (sessionContainer != null) {

+            pwr.publishAdapters(sessionContainer.getComponentAdapters(), SESSION_SCOPE);

+        }

         pwr.publishAdapters(currentAppContainer.get().getComponentAdapters(), APPLICATION_SCOPE);

 

         monitor = currentAppContainer.get().getComponent(PicoWebRemotingMonitor.class);

 


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email


Re: RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

by Paul Hammant-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Not so much cool Mike, but necessary for AppEngine deployment.

There's a bug that remains that's exposed by AppEngine.  Session components that dep on App Components that are serialized to the session at the end of a request, will also serialize the app instance.  This is not a bug for non session-serializing servlet containers (like Jetty/Tomcat standalone).

We're going to have to implement Guice's provider style injector (Provider Injection as opposed to Dependency Injection) as well as an (alternate) ASM mechanism to subvert the app scoped comps from being serialized (transient will suffice) as well reconstitute the app-comp connections on de-serialization.

Regards,

- Paul

On Jun 9, 2009, at 5:19 PM, Michael Rimov wrote:

Woo hoo! :)
 
Very cool Paul!
                                                                                                                                                                -Mike
 

RE: RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

by Michael Rimov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Actually Paul,

 

This is EXACTLY an issue in Tomcat.   Its why on NanoWAR branch, I made the Session container optional (I never used it personally because of this).

 

I had made a couple of peeks at the Pico-web-2 code to see if I could easily see how to work around it, but no dice --but when I saw the patch, I understood the result of what you were working on and thus the “WOO HOO!”

 

So, sorry Paul, you’re still going to get lots of appreciation from me for this current branch of work…..   and you can’t stop me :) 

 

                                                                                                                                                -Mike

 

 

From: Paul Hammant [mailto:paul@...]
Sent: Thursday, June 11, 2009 9:36 AM
To: dev@...
Subject: Re: [picocontainer-dev] RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

 

Not so much cool Mike, but necessary for AppEngine deployment.

 

There's a bug that remains that's exposed by AppEngine.  Session components that dep on App Components that are serialized to the session at the end of a request, will also serialize the app instance.  This is not a bug for non session-serializing servlet containers (like Jetty/Tomcat standalone).

 

We're going to have to implement Guice's provider style injector (Provider Injection as opposed to Dependency Injection) as well as an (alternate) ASM mechanism to subvert the app scoped comps from being serialized (transient will suffice) as well reconstitute the app-comp connections on de-serialization.

 

Regards,

 

- Paul

 

On Jun 9, 2009, at 5:19 PM, Michael Rimov wrote:



Woo hoo! :)

 

Very cool Paul!

                                                                                                                                                                -Mike

 


Re: RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

by Paul Hammant-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

It's being stateful that I'm most interested in. Google want us to be stateless on appengine to achieve mega scale. However average enterprise devs are going to use the session store for stuff, so I really want to get it working.

There's a speed mismatch too. Being stateful (a mere 500 bytes written to the session) is adding 90ms to response time. Crude benchmarking of course....

Sent from my iPhone

On Jun 11, 2009, at 12:03 PM, "Michael Rimov" <rimovm@...> wrote:

Actually Paul,

 

This is EXACTLY an issue in Tomcat.   Its why on NanoWAR branch, I made the Session container optional (I never used it personally because of this).

 

I had made a couple of peeks at the Pico-web-2 code to see if I could easily see how to work around it, but no dice --but when I saw the patch, I understood the result of what you were working on and thus the “WOO HOO!”

 

So, sorry Paul, you’re still going to get lots of appreciation from me for this current branch of work…..   and you can’t stop me :) 

 

                                                                                                                                                -Mike

 

 

From: Paul Hammant [paul@...]
Sent: Thursday, June 11, 2009 9:36 AM
To: dev@...
Subject: Re: [picocontainer-dev] RE: [picocontainer-scm] [5426] java/2.x/trunk/web/web-core/src/java/org/picocontainer/web: make stateless not hit session.setAttribute()

 

Not so much cool Mike, but necessary for AppEngine deployment.

 

There's a bug that remains that's exposed by AppEngine.  Session components that dep on App Components that are serialized to the session at the end of a request, will also serialize the app instance.  This is not a bug for non session-serializing servlet containers (like Jetty/Tomcat standalone).

 

We're going to have to implement Guice's provider style injector (Provider Injection as opposed to Dependency Injection) as well as an (alternate) ASM mechanism to subvert the app scoped comps from being serialized (transient will suffice) as well reconstitute the app-comp connections on de-serialization.

 

Regards,

 

- Paul

 

On Jun 9, 2009, at 5:19 PM, Michael Rimov wrote:



Woo hoo! :)

 

Very cool Paul!

                                                                                                                                                                -Mike