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.lang.management.ManagementFactory;
22 import java.util.concurrent.CopyOnWriteArrayList;
23
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
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
178 LOG.debug(STARTED+" @{}ms {}",ManagementFactory.getRuntimeMXBean().getUptime(),this);
179 for (Listener listener : _listeners)
180 listener.lifeCycleStarted(this);
181 }
182
183 private void setStarting()
184 {
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 LOG.debug("stopping {}",this);
194 _state = __STOPPING;
195 for (Listener listener : _listeners)
196 listener.lifeCycleStopping(this);
197 }
198
199 private void setStopped()
200 {
201 _state = __STOPPED;
202 LOG.debug("{} {}",STOPPED,this);
203 for (Listener listener : _listeners)
204 listener.lifeCycleStopped(this);
205 }
206
207 private void setFailed(Throwable th)
208 {
209 _state = __FAILED;
210 LOG.warn(FAILED+" " + this+": "+th,th);
211 for (Listener listener : _listeners)
212 listener.lifeCycleFailure(this,th);
213 }
214
215 @ManagedAttribute(value="The stop timeout in milliseconds")
216 public long getStopTimeout()
217 {
218 return _stopTimeout;
219 }
220
221 public void setStopTimeout(long stopTimeout)
222 {
223 this._stopTimeout = stopTimeout;
224 }
225
226 public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
227 {
228 @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
229 @Override public void lifeCycleStarted(LifeCycle event) {}
230 @Override public void lifeCycleStarting(LifeCycle event) {}
231 @Override public void lifeCycleStopped(LifeCycle event) {}
232 @Override public void lifeCycleStopping(LifeCycle event) {}
233 }
234 }