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  import org.apache.myfaces.orchestra.conversation.basic.LogConversationMessager;
    28  import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
    29  import org.apache.myfaces.orchestra.frameworkAdapter.local.LocalFrameworkAdapter;
    30
    31  /**
    32   * The ConversationWiperThread will trigger the conversation timeout check.
    33   * <p>
    34   * This is typically started from a servlet session listener when the webapp starts.
    35   *
    36   * @see org.apache.myfaces.orchestra.conversation.servlet.ConversationManagerSessionListener
    37   */
    38  public class ConversationWiperThread extends Thread
    39  {
    40      private final Log log = LogFactory.getLog(ConversationWiperThread.class);
    41
    42      private final long checkTime;
    43
    44      private Set conversationManagers = new HashSet();
    45
    46      /**
    47       * Constructor.
    48       *
    49       * @param checkTime is interval in milliseconds between scans of the existing
    50       * ConversationManagers to look for timeouts.
    51       */
    52      public ConversationWiperThread(long checkTime)
    53      {
    54          this.checkTime = checkTime;
    55
    56          setDaemon(true);
    57          setName(ConversationWiperThread.class.getName());
    58      }
    59
    60      /**
    61       * Add a ConversationManager to check.
    62       *
    63       * @since 1.1
    64       */
    65      public void addConversationManager(ConversationManager cm)
    66      {
    67          synchronized (conversationManagers)
    68          {
    69              conversationManagers.add(cm);
    70          }
    71      }
    72
    73      /**
    74       * Remove a ConversationManager from the list to check.
    75       *
    76       * @since 1.1
    77       */
    78      public void removeConversationManager(ConversationManager cm)
    79      {
    80          synchronized (conversationManagers)
    81          {
    82              boolean found = conversationManagers.remove(cm);
    83              if (!found)
    84              {
    85                  // sanity check: this should not happen.
    86                  log.error("Conversation Manager not found in remove");
    87              }
    88          }
    89      }
    90
    91      public void run()
    92      {
    93          if (log.isDebugEnabled())
    94          {
    95              log.debug("ConversationWiperThread startup"); // NON-NLS
    96          }
    97          _run();
    98          if (log.isDebugEnabled())
    99          {
    100             log.debug("ConversationWiperThread shtudown"); // NON-NLS
    101         }
    102     }
    103
    104     private void _run()
    105     {
    106         // Set up a custom FrameworkAdapter for this thread, so other orchestra code used by this
    107         // thread which expects one to exist will not throw NullPointerException.
    108         FrameworkAdapter fa = new LocalFrameworkAdapter();
    109         ConversationMessager conversationMessager = new LogConversationMessager();
    110         fa.setConversationMessager(conversationMessager);
    111         FrameworkAdapter.setCurrentInstance(fa);
    112
    113         while (!isInterrupted())
    114         {
    115             ConversationManager[] managersArray;
    116             synchronized (conversationManagers)
    117             {
    118                 managersArray = new ConversationManager[conversationManagers.size()];
    119                 conversationManagers.toArray(managersArray);
    120             }
    121
    122             if (log.isDebugEnabled())
    123             {
    124                 log.debug("ConversationWiperThread running against " + managersArray.length + " instances.");
    125             }
    126
    127             for (int i = 0; i<managersArray.length; i++)
    128             {
    129                 ConversationManager conversationManager = managersArray[i];
    130                 conversationManager.checkTimeouts();
    131             }
    132
    133             try
    134             {
    135                 Thread.sleep(checkTime);
    136             }
    137             catch (InterruptedException e)
    138             {
    139                 return;
    140             }
    141         }
    142     }
    143 }