View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.conversation;
20  
21  import java.util.HashSet;
22  import java.util.Set;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  /**
28   * The ConversationWiperThread will trigger the conversation timeout check.
29   * <p>
30   * This is typically started from a servlet session listener when the webapp starts.
31   * 
32   * @see org.apache.myfaces.orchestra.conversation.servlet.ConversationManagerSessionListener
33   */
34  public class ConversationWiperThread extends Thread
35  {
36      private final Log log = LogFactory.getLog(ConversationWiperThread.class);
37  
38      private final long checkTime;
39  
40      private Set conversationManagers = new HashSet();
41  
42      /**
43       * Constructor.
44       * 
45       * @param checkTime is interval in milliseconds between scans of the existing
46       * ConversationManagers to look for timeouts.
47       */
48      public ConversationWiperThread(long checkTime)
49      {
50          this.checkTime = checkTime;
51  
52          setDaemon(true);
53          setName(ConversationWiperThread.class.getName());
54      }
55  
56      /**
57       * Add a ConversationManager to check.
58       * 
59       * @since 1.1
60       */
61      public void addConversationManager(ConversationManager cm)
62      {
63          synchronized (conversationManagers)
64          {
65              conversationManagers.add(cm);
66          }
67      }
68  
69      /**
70       * Remove a ConversationManager from the list to check.
71       * 
72       * @since 1.1
73       */
74      public void removeConversationManager(ConversationManager cm)
75      {
76          synchronized (conversationManagers)
77          {
78              boolean found = conversationManagers.remove(cm);
79              if (!found)
80              {
81                  // sanity check: this should not happen.
82                  log.error("Conversation Manager not found in remove");
83              }
84          }
85      }
86  
87      public void run()
88      {
89          log.debug("ConversationWiperThread startup"); // NON-NLS
90          _run();
91          log.debug("ConversationWiperThread shtudown"); // NON-NLS
92      }
93  
94      private void _run()
95      {
96          while (!isInterrupted())
97          {
98              ConversationManager[] managersArray;
99              synchronized (conversationManagers)
100             {
101                 managersArray = new ConversationManager[conversationManagers.size()];
102                 conversationManagers.toArray(managersArray);
103             }
104 
105             if (log.isDebugEnabled())
106             {
107                 log.debug("ConversationWiperThread running against " + managersArray.length + " instances.");
108             }
109 
110             for (int i = 0; i<managersArray.length; i++)
111             {
112                 ConversationManager conversationManager = managersArray[i];
113                 conversationManager.checkTimeouts();
114             }
115 
116             try
117             {
118                 Thread.sleep(checkTime);
119             }
120             catch (InterruptedException e)
121             {
122                 return;
123             }
124         }
125     }
126 }