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.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
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 }