3 Replies Latest reply on Oct 24, 2008 8:54 AM by Nikolay Elenkov

    SFSB not removed when conversation ends?

    Nikolay Elenkov Master

      Hello,


      I am having some performance problems with my app and I am checking for leaks.
      I have a simple listeners that dumps session attributes on every add/remove/replace.


      When I end a conversation, all entities are removed from the session, as expected. However,
      manager components (SFSB's) are left over. Repeatedly starting and ending a conversation results
      in something like (17, 18, 19 have ended, all other attributes for those conversations have been
      removed from session; 20 is active):


      20:11:12,440 INFO  [STDOUT] org.jboss.seam.CONVERSATION#17$userManager
      20:11:12,440 INFO  [STDOUT] org.jboss.seam.CONVERSATION#18$userManager
      20:11:12,440 INFO  [STDOUT] org.jboss.seam.CONVERSATION#19$userManager
      20:11:12,440 INFO  [STDOUT] org.jboss.seam.CONVERSATION#20$userManager
      20:11:12,440 INFO  [STDOUT] org.jboss.seam.CONVERSATION#20$user
      



      I tried manually removing the component in its destroy method, but that does not seem to work.
      The code is:


       @Remove
       @Destroy
       public void destroy() {
              log.trace("destroy");
              Context ctx = Contexts.getConversationContext();
              Object obj = ctx.get("userManager");
              System.out.println("### userManager: " + obj);
              System.out.println("$$$ context: " + ctx);
              ctx.remove("userManager");
          }
      



      Am I missing something obvious? I looked at ServerConversationContext and there does not seem to be
      anything special I need to do to remove a component from the conversation.


      TIA


        • 1. Re: SFSB not removed when conversation ends?
          Nikolay Elenkov Master

          Adding ctx.flush() to destroy() changes nothing. SFSB's are still left over.

          • 2. Re: SFSB not removed when conversation ends?
            Nikolay Elenkov Master

            It seems that SFSB's are not removed if the conversation is a temporary one.


            Here's what (I think) happens:



            1. Conversation ended by @End or pages.xml

            2. @Remove @Destroy destroy() is called

            3. RemoveInterceptor calls ServerConversationContext#remove(). That results in the component's name being added to ServerConversationContext#removals.

            4. When ServerConversationContext.flush() is called, names in the removals list are not actually removed from the session, because the conversation is temporary (see *** below)



             public void flush()
               {      
                  boolean longRunning = !isCurrent() || Manager.instance().isLongRunningConversation();  
                      
                  if ( longRunning )
                  {
                      //force update for dirty mutable objects
                      for (String key: getNamesForAllConversationsFromSession())  {
                          Object attribute = session.get(key);
                        
                          if (attribute!=null) {
                              if (passivate(attribute) || isAttributeDirty(attribute)) {
                                  session.put(key, attribute);
                              }
                          }
                      }
            
                      //remove removed objects
                      for (String name: removals) {
                          session.remove(getKey(name));
                      }
                      removals.clear();
            
                      //add new objects
                      for (Map.Entry<String, Object> entry: additions.entrySet())  {
                          Object attribute = entry.getValue();
            
                          passivate(attribute); 
                          session.put(getKey(entry.getKey()), attribute);
                      }
                      additions.clear();
                  }
                  else
                  {
                     //TODO: for a pure temporary conversation, this is unnecessary, optimize it
                     // *** Here: getNamesFromSession does not include removals, so they are left over
                     // Should probably be like this:
                     
                     // added code START
                     //for (String name: removals) {
                     //     session.remove(getKey(name));
                     //}
                     //removals.clear();
                     // added code END
            
                     for ( String name: getNamesFromSession() )
                     {
                        session.remove( getKey(name) );
                     }
                  }
               }