View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.util.component;
20  
21  import java.util.concurrent.CopyOnWriteArrayList;
22  
23  import org.eclipse.jetty.util.Uptime;
24  import org.eclipse.jetty.util.annotation.ManagedAttribute;
25  import org.eclipse.jetty.util.annotation.ManagedObject;
26  import org.eclipse.jetty.util.log.Log;
27  import org.eclipse.jetty.util.log.Logger;
28  
29  /**
30   * Basic implementation of the life cycle interface for components.
31   */
32  @ManagedObject("Abstract Implementation of LifeCycle")
33  public abstract class AbstractLifeCycle implements LifeCycle
34  {
35      private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
36      
37      public static final String STOPPED="STOPPED";
38      public static final String FAILED="FAILED";
39      public static final String STARTING="STARTING";
40      public static final String STARTED="STARTED";
41      public static final String STOPPING="STOPPING";
42      public static final String RUNNING="RUNNING";
43  
44      private final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
45      private final Object _lock = new Object();
46      private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3;
47      private volatile int _state = __STOPPED;
48      private long _stopTimeout = 30000;
49  
50      protected void doStart() throws Exception
51      {
52      }
53  
54      protected void doStop() throws Exception
55      {
56      }
57      
58      @Override
59      public final void start() throws Exception
60      {
61          synchronized (_lock)
62          {
63              try
64              {
65                  if (_state == __STARTED || _state == __STARTING)
66                      return;
67                  setStarting();
68                  doStart();
69                  setStarted();
70              }
71              catch (Throwable e)
72              {
73                  setFailed(e);
74                  throw e;
75              }
76          }
77      }
78  
79      @Override
80      public final void stop() throws Exception
81      {
82          synchronized (_lock)
83          {
84              try
85              {
86                  if (_state == __STOPPING || _state == __STOPPED)
87                      return;
88                  setStopping();
89                  doStop();
90                  setStopped();
91              }
92              catch (Throwable e)
93              {
94                  setFailed(e);
95                  throw e;
96              }
97          }
98      }
99  
100     @Override
101     public boolean isRunning()
102     {
103         final int state = _state;
104 
105         return state == __STARTED || state == __STARTING;
106     }
107 
108     @Override
109     public boolean isStarted()
110     {
111         return _state == __STARTED;
112     }
113 
114     @Override
115     public boolean isStarting()
116     {
117         return _state == __STARTING;
118     }
119 
120     @Override
121     public boolean isStopping()
122     {
123         return _state == __STOPPING;
124     }
125 
126     @Override
127     public boolean isStopped()
128     {
129         return _state == __STOPPED;
130     }
131 
132     @Override
133     public boolean isFailed()
134     {
135         return _state == __FAILED;
136     }
137 
138     @Override
139     public void addLifeCycleListener(LifeCycle.Listener listener)
140     {
141         _listeners.add(listener);
142     }
143 
144     @Override
145     public void removeLifeCycleListener(LifeCycle.Listener listener)
146     {
147         _listeners.remove(listener);
148     }
149 
150     @ManagedAttribute(value="Lifecycle State for this instance", readonly=true)
151     public String getState()
152     {
153         switch(_state)
154         {
155             case __FAILED: return FAILED;
156             case __STARTING: return STARTING;
157             case __STARTED: return STARTED;
158             case __STOPPING: return STOPPING;
159             case __STOPPED: return STOPPED;
160         }
161         return null;
162     }
163 
164     public static String getState(LifeCycle lc)
165     {
166         if (lc.isStarting()) return STARTING;
167         if (lc.isStarted()) return STARTED;
168         if (lc.isStopping()) return STOPPING;
169         if (lc.isStopped()) return STOPPED;
170         return FAILED;
171     }
172 
173     private void setStarted()
174     {
175         _state = __STARTED;
176         if (LOG.isDebugEnabled())
177             LOG.debug(STARTED+" @{}ms {}",Uptime.getUptime(),this);
178         for (Listener listener : _listeners)
179             listener.lifeCycleStarted(this);
180     }
181 
182     private void setStarting()
183     {
184         if (LOG.isDebugEnabled())
185             LOG.debug("starting {}",this);
186         _state = __STARTING;
187         for (Listener listener : _listeners)
188             listener.lifeCycleStarting(this);
189     }
190 
191     private void setStopping()
192     {
193         if (LOG.isDebugEnabled())
194             LOG.debug("stopping {}",this);
195         _state = __STOPPING;
196         for (Listener listener : _listeners)
197             listener.lifeCycleStopping(this);
198     }
199 
200     private void setStopped()
201     {
202         _state = __STOPPED;
203         if (LOG.isDebugEnabled())
204             LOG.debug("{} {}",STOPPED,this);
205         for (Listener listener : _listeners)
206             listener.lifeCycleStopped(this);
207     }
208 
209     private void setFailed(Throwable th)
210     {
211         _state = __FAILED;
212         if (LOG.isDebugEnabled())
213             LOG.warn(FAILED+" " + this+": "+th,th);
214         for (Listener listener : _listeners)
215             listener.lifeCycleFailure(this,th);
216     }
217 
218     @ManagedAttribute(value="The stop timeout in milliseconds")
219     public long getStopTimeout()
220     {
221         return _stopTimeout;
222     }
223 
224     public void setStopTimeout(long stopTimeout)
225     {
226         this._stopTimeout = stopTimeout;
227     }
228 
229     public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
230     {
231         @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
232         @Override public void lifeCycleStarted(LifeCycle event) {}
233         @Override public void lifeCycleStarting(LifeCycle event) {}
234         @Override public void lifeCycleStopped(LifeCycle event) {}
235         @Override public void lifeCycleStopping(LifeCycle event) {}
236     }
237 }