You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by rm...@apache.org on 2014/12/29 08:20:35 UTC

svn commit: r1648291 - in /openwebbeans/trunk: webbeans-impl/src/main/java/org/apache/webbeans/conversation/ webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/ webbeans-web/src/main/java/org/apac...

Author: rmannibucau
Date: Mon Dec 29 07:20:35 2014
New Revision: 1648291

URL: http://svn.apache.org/r1648291
Log:
allowing better check on conversation if it is busy or not - main issue is we dont control cause of our spi where a boolean is set (servlet layer? jsf layer?...) so we need to support multiple calls by thread + avoid to serialize the conversation itself but use conversation manager for it

Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java
    openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java
    openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java?rev=1648291&r1=1648290&r2=1648291&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java Mon Dec 29 07:20:35 2014
@@ -18,14 +18,15 @@
  */
 package org.apache.webbeans.conversation;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
+import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.enterprise.context.BusyConversationException;
 import javax.enterprise.context.ContextNotActiveException;
 import javax.enterprise.context.Conversation;
 import javax.enterprise.context.ConversationScoped;
@@ -71,8 +72,13 @@ public class ConversationImpl implements
     /**Generating ids*/
     private static AtomicInteger conversationIdGenerator = new AtomicInteger(0);
     
-    /**This instance is under used*/
-    private AtomicBoolean inUsed = new AtomicBoolean(false);
+    /**
+     This instance is under used and by which threads, Atomicinteger would be great but then contract of ContextsService but be enhanced to
+     be compatible wih WBPhaseListeners. Using thread allow to call iUseIt() multiple times.
+     String to be serializable.
+     TODO: serialization should be done manually to use the manager otherwise all is broken
+     */
+    private Set<Long> threadsUsingIt = new HashSet<Long>();
 
     private transient WebBeansContext webBeansContext;
 
@@ -134,6 +140,7 @@ public class ConversationImpl implements
         {
             isTransient = false;
             id = Integer.toString(conversationIdGenerator.incrementAndGet());
+            iUseIt();
             updateTimeOut();
 
             //Conversation manager
@@ -184,7 +191,7 @@ public class ConversationImpl implements
      */
     @Override
     public void begin(String id)
-    {   
+    {
         //Look at other conversation, that may collate with this is
         final ConversationManager conversationManager = webBeansContext.getConversationManager();
         if(conversationManager.isConversationExistWithGivenId(id))
@@ -197,6 +204,7 @@ public class ConversationImpl implements
         {
             isTransient = false;
             this.id = id;
+            iUseIt();
             if (this.sessionId == null)
             {
                 OpenWebBeansWebPlugin web = webBeansContext.getPluginLoader().getWebPlugin();
@@ -217,10 +225,11 @@ public class ConversationImpl implements
     @Override
     public void end()
     {
+        check();
         if(!isTransient)
         {
             isTransient = true;
-
+            iDontUseItAnymore();
             webBeansContext.getConversationManager().removeConversation(this);
         }
         else
@@ -229,22 +238,24 @@ public class ConversationImpl implements
             throw new IllegalStateException(toString() + " has already ended");
         }
     }
-    
-    
-    /**
-     * @return the inUsed
-     */
-    public AtomicBoolean getInUsed()
+
+    public int iUseIt()
     {
-        return inUsed;
+        long thread = Thread.currentThread().getId();
+        synchronized (this)
+        {
+            threadsUsingIt.add(thread);
+            return threadsUsingIt.size();
+        }
     }
 
-    /**
-     * @param inUsed the inUsed to set
-     */
-    public void setInUsed(boolean inUsed)
+    public void iDontUseItAnymore()
     {
-        this.inUsed.set(inUsed);
+        long thread = Thread.currentThread().getId();
+        synchronized (this)
+        {
+            threadsUsingIt.remove(thread);
+        }
     }
     
     /**
@@ -262,6 +273,7 @@ public class ConversationImpl implements
     @Override
     public long getTimeout()
     {
+        check();
         return timeout;
     }
 
@@ -271,15 +283,26 @@ public class ConversationImpl implements
     @Override
     public boolean isTransient()
     {
+        check();
         return isTransient;
     }
-    
+
+    private synchronized void check()
+    {
+        if (threadsUsingIt.size() > 1)
+        {
+            throw new BusyConversationException(
+                    "Propogated conversation with sessionid/cid=" + sessionId + "/" + id + " is used by other request.");
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
     @Override
     public void setTimeout(long milliseconds)
     {
+        check();
         timeout = milliseconds;
     }
 
@@ -375,21 +398,36 @@ public class ConversationImpl implements
     @Override
     public String toString()
     {
-        StringBuilder builder = new StringBuilder();
-        builder.append("Conversation with id [ ");
-        builder.append(id);
-        builder.append(" ]");
-        
-        return builder.toString();
+        return "Conversation with id [ " + id + " ]";
     }
 
-    /**
-     * We need this for restoring our WebBeansContext on de-serialisation
-     */
-    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+    private Object writeReplace() throws ObjectStreamException
     {
-        webBeansContext = WebBeansContext.currentInstance();
-        in.defaultReadObject();
+        Serialization serialization = new Serialization();
+        serialization.setId(id);
+        serialization.setSessionId(sessionId);
+        return serialization;
     }
 
+    public static class Serialization implements Serializable
+    {
+        private String sessionId;
+        private String id;
+
+        public void setSessionId(String sessionId)
+        {
+            this.sessionId = sessionId;
+        }
+
+        public void setId(String id)
+        {
+            this.id = id;
+        }
+
+        Object  readResolve() throws ObjectStreamException
+        {
+            return WebBeansContext.currentInstance().getConversationManager().getPropogatedConversation(id, sessionId);
+        }
+    }
 }
+

Modified: openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java?rev=1648291&r1=1648290&r2=1648291&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java Mon Dec 29 07:20:35 2014
@@ -85,7 +85,7 @@ public class WebBeansPhaseListener imple
                 ConversationImpl owbConversation = (ConversationImpl)conversation;
                 owbConversation.updateTimeOut();
                 //Other threads can now access propogated conversation.
-                owbConversation.setInUsed(false);                
+                owbConversation.iDontUseItAnymore();
             }            
         }
     }
@@ -137,7 +137,7 @@ public class WebBeansPhaseListener imple
 
                 //Conversation must be used by one thread at a time
                 ConversationImpl owbConversation = (ConversationImpl)conversation;
-                if(!owbConversation.getInUsed().compareAndSet(false, true))
+                if(owbConversation.iUseIt() > 1)
                 {
                     contextFactory.initConversationContext(getRequest(phaseEvent));
                     //Throw Busy exception

Modified: openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java?rev=1648291&r1=1648290&r2=1648291&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java (original)
+++ openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java Mon Dec 29 07:20:35 2014
@@ -83,7 +83,7 @@ public class WebBeansPhaseListener imple
                 ConversationImpl owbConversation = (ConversationImpl)conversation;
                 owbConversation.updateTimeOut();
                 //Other threads can now access propogated conversation.
-                owbConversation.setInUsed(false);                
+                owbConversation.iDontUseItAnymore();
             }            
         }
     }
@@ -133,7 +133,7 @@ public class WebBeansPhaseListener imple
 
                 //Conversation must be used by one thread at a time
                 ConversationImpl owbConversation = (ConversationImpl)conversation;
-                if(!owbConversation.getInUsed().compareAndSet(false, true))
+                if(owbConversation.iUseIt() > 1)
                 {
                     contextFactory.initConversationContext(null);
                     //Throw Busy exception

Modified: openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java?rev=1648291&r1=1648290&r2=1648291&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java (original)
+++ openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java Mon Dec 29 07:20:35 2014
@@ -173,7 +173,10 @@ public class WebContextsService extends
         
         //Destroy singleton context
         endContext(Singleton.class, destroyObject);
-        sharedSingletonContext.destroy();
+        if (sharedSingletonContext != null)
+        {
+            sharedSingletonContext.destroy();
+        }
 
         //Clear saved contexts related with 
         //this servlet context
@@ -438,7 +441,7 @@ public class WebContextsService extends
             ConversationImpl owbConversation = (ConversationImpl)conversation;
             owbConversation.updateTimeOut();
             //Other threads can now access propogated conversation.
-            owbConversation.setInUsed(false);
+            owbConversation.iDontUseItAnymore();
         }
     }