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  
20  
21  package org.apache.james.util.watchdog;
22  
23  import org.apache.avalon.cornerstone.services.scheduler.PeriodicTimeTrigger;
24  import org.apache.avalon.cornerstone.services.scheduler.Target;
25  import org.apache.avalon.cornerstone.services.scheduler.TimeScheduler;
26  
27  /**
28   * This class is a factory to produce Watchdogs, each of which is associated
29   * with a single TimeScheduler Target and a TimeScheduler object.
30   *
31   * This could be used in James by adding a server configuration
32   * parameter:
33   *
34   *     schedulerWatchdogs = conf.getChild("useSchedulerWatchdogs").getValueAsBoolean(false);
35   *
36   * getting the TimeScheduler component:
37   *
38   *     scheduler = (TimeScheduler) compMgr.lookup(TimeScheduler.ROLE);
39   *
40   * and changing AbstractJamesService.getWatchdogFactory to look
41   * something like: 
42   *
43   *     protected WatchdogFactory getWatchdogFactory() {
44   *        WatchdogFactory theWatchdogFactory = null;
45   *        if (schedulerWatchdogs) {
46   *             theWatchdogFactory = new SchedulerWatchdogFactory(scheduler, timeout);
47   *           } else {
48   *             theWatchdogFactory = new ThreadPerWatchdogFactory(threadPool, timeout);
49   *           }
50   *        if (theWatchdogFactory instanceof LogEnabled) {
51   *             ((LogEnabled)theWatchdogFactory).enableLogging(getLogger());
52   *        }
53   *        return theWatchdogFactory;
54   *     }
55   *
56   */
57  public class SchedulerWatchdogFactory implements WatchdogFactory {
58  
59      /**
60       * The thread pool used to generate InaccurateTimeoutWatchdogs
61       */
62      private TimeScheduler myTimeScheduler;
63  
64      private long timeout = -1;
65  
66      /**
67       * Creates the factory and sets the TimeScheduler used to implement
68       * the watchdogs.
69       *
70       * @param theTimeScheduler the scheduler that manages Watchdog triggering
71       *                         for Watchdogs produced by this factory
72       * @param timeout the timeout for Watchdogs produced by this factory
73       */
74      public SchedulerWatchdogFactory(TimeScheduler theTimeScheduler, long timeout) {
75          this.timeout = timeout;
76          myTimeScheduler = theTimeScheduler;
77      }
78  
79      /**
80       * @see org.apache.james.util.watchdog.WatchdogFactory#getWatchdog(WatchdogTarget)
81       */
82      public Watchdog getWatchdog(WatchdogTarget theTarget) {
83          return new SchedulerWatchdog(theTarget);
84      }
85  
86      /**
87       * An inner class that acts as an adaptor between the Watchdog
88       * interface and the TimeScheduler interface.
89       */
90      private class SchedulerWatchdog implements Watchdog {
91  
92          /**
93           * The in-scheduler identifier for this trigger.
94           */
95          private String triggerID = null;
96  
97          /**
98           * The WatchdogTarget that is passed in when this
99           * SchedulerWatchdog is initialized
100          */
101         private WatchdogTarget theWatchdogTarget;
102 
103         /**
104          * Constructor for the SchedulerWatchdog
105          *
106          * @param theTarget the target triggered by this Watchdog
107          */
108         SchedulerWatchdog(WatchdogTarget theTarget) {
109             // TODO: This should be made more robust then just
110             //       using toString()
111             triggerID = this.toString();
112             theWatchdogTarget = theTarget;
113         }
114 
115         /**
116          * Start this Watchdog, causing it to begin monitoring.  The Watchdog can
117          * be stopped and restarted.
118          */
119         public void start() {
120             PeriodicTimeTrigger theTrigger = new PeriodicTimeTrigger((int)SchedulerWatchdogFactory.this.timeout, -1);
121             Target theTarget = new Target() {
122                                     public void targetTriggered(String targetID) {
123                                         theWatchdogTarget.execute();
124                                     }
125                                };
126             SchedulerWatchdogFactory.this.myTimeScheduler.addTrigger(triggerID, theTrigger, theTarget);
127         }
128 
129         /**
130          * Reset this Watchdog.  Resets any conditions in the implementations
131          * (time to expiration, etc.) to their original values
132          */
133         public void reset() {
134             SchedulerWatchdogFactory.this.myTimeScheduler.resetTrigger(triggerID);
135         }
136 
137         /**
138          * Stop this Watchdog, terminating the monitoring condition.  The monitor
139          * can be restarted with a call to startWatchdog.
140          */
141         public void stop() {
142             SchedulerWatchdogFactory.this.myTimeScheduler.removeTrigger(triggerID);
143         }
144     }
145 
146 }