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