1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.mule.impl.work;
29
30 import org.mule.MuleManager;
31 import org.mule.config.ThreadingProfile;
32 import org.mule.umo.UMOException;
33 import org.mule.umo.manager.UMOWorkManager;
34
35 import java.util.List;
36
37 import javax.resource.spi.XATerminator;
38 import javax.resource.spi.work.ExecutionContext;
39 import javax.resource.spi.work.Work;
40 import javax.resource.spi.work.WorkCompletedException;
41 import javax.resource.spi.work.WorkException;
42 import javax.resource.spi.work.WorkListener;
43
44 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
45 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
46 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
47
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50
51
52
53
54
55
56 public class MuleWorkManager implements UMOWorkManager
57 {
58
59
60
61 protected static final Log logger = LogFactory.getLog(MuleWorkManager.class);
62
63
64
65
66 private static final long SHUTDOWN_TIMEOUT = 5000L;
67
68
69
70
71 private final ThreadingProfile threadingProfile;
72
73
74
75
76
77 private volatile ExecutorService workExecutorService;
78 private final String name;
79
80
81
82
83 private final WorkExecutor scheduleWorkExecutor = new ScheduleWorkExecutor();
84 private final WorkExecutor startWorkExecutor = new StartWorkExecutor();
85 private final WorkExecutor syncWorkExecutor = new SyncWorkExecutor();
86
87 public MuleWorkManager()
88 {
89 this(MuleManager.getConfiguration().getDefaultThreadingProfile(), null);
90 }
91
92 public MuleWorkManager(ThreadingProfile profile, String name)
93 {
94 super();
95
96 if (name == null)
97 {
98 name = "WorkManager#" + hashCode();
99 }
100
101 this.threadingProfile = profile;
102 this.name = name;
103 }
104
105 public synchronized void start() throws UMOException
106 {
107 if (workExecutorService == null)
108 {
109 workExecutorService = threadingProfile.createPool(name);
110 }
111 }
112
113 public synchronized void stop() throws UMOException
114 {
115 if (workExecutorService != null)
116 {
117 try
118 {
119
120 List outstanding = workExecutorService.shutdownNow();
121
122
123 if (!workExecutorService.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS))
124 {
125 logger.warn("Pool " + name + " did not terminate in time; " + outstanding.size()
126 + " work items were cancelled.");
127 }
128 }
129 catch (InterruptedException ie)
130 {
131
132 workExecutorService.shutdownNow();
133
134 Thread.currentThread().interrupt();
135 }
136 finally
137 {
138 workExecutorService = null;
139 }
140 }
141 }
142
143 public void dispose()
144 {
145 try
146 {
147 stop();
148 }
149 catch (UMOException e)
150 {
151
152 logger.warn("Error while disposing Work Manager: " + e.getMessage(), e);
153 }
154 }
155
156
157 public XATerminator getXATerminator()
158 {
159 return null;
160 }
161
162
163
164
165
166
167 public void doWork(Work work) throws WorkException
168 {
169 executeWork(new WorkerContext(work), syncWorkExecutor);
170 }
171
172
173
174
175
176
177
178
179 public void doWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener)
180 throws WorkException
181 {
182 WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
183 workWrapper.setThreadPriority(Thread.currentThread().getPriority());
184 executeWork(workWrapper, syncWorkExecutor);
185 }
186
187
188
189
190
191
192 public long startWork(Work work) throws WorkException
193 {
194 WorkerContext workWrapper = new WorkerContext(work);
195 workWrapper.setThreadPriority(Thread.currentThread().getPriority());
196 executeWork(workWrapper, startWorkExecutor);
197 return System.currentTimeMillis() - workWrapper.getAcceptedTime();
198 }
199
200
201
202
203
204
205
206
207 public long startWork(Work work,
208 long startTimeout,
209 ExecutionContext execContext,
210 WorkListener workListener) throws WorkException
211 {
212 WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
213 workWrapper.setThreadPriority(Thread.currentThread().getPriority());
214 executeWork(workWrapper, startWorkExecutor);
215 return System.currentTimeMillis() - workWrapper.getAcceptedTime();
216 }
217
218
219
220
221
222
223 public void scheduleWork(Work work) throws WorkException
224 {
225 WorkerContext workWrapper = new WorkerContext(work);
226 workWrapper.setThreadPriority(Thread.currentThread().getPriority());
227 executeWork(workWrapper, scheduleWorkExecutor);
228 }
229
230
231
232
233
234
235
236
237 public void scheduleWork(Work work,
238 long startTimeout,
239 ExecutionContext execContext,
240 WorkListener workListener) throws WorkException
241 {
242 WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
243 workWrapper.setThreadPriority(Thread.currentThread().getPriority());
244 executeWork(workWrapper, scheduleWorkExecutor);
245 }
246
247
248
249
250 public void execute(Runnable work)
251 {
252 if (workExecutorService == null || workExecutorService.isShutdown())
253 {
254 throw new IllegalStateException("This MuleWorkManager is stopped");
255 }
256
257 workExecutorService.execute(work);
258 }
259
260
261
262
263
264
265
266
267 private void executeWork(WorkerContext work, WorkExecutor workExecutor) throws WorkException
268 {
269 if (workExecutorService == null || workExecutorService.isShutdown())
270 {
271 throw new IllegalStateException("This MuleWorkManager is stopped");
272 }
273
274 try
275 {
276 work.workAccepted(this);
277 workExecutor.doExecute(work, workExecutorService);
278 WorkException exception = work.getWorkException();
279 if (null != exception)
280 {
281 throw exception;
282 }
283 }
284 catch (InterruptedException e)
285 {
286 WorkCompletedException wcj = new WorkCompletedException("The execution has been interrupted.", e);
287 wcj.setErrorCode(WorkException.INTERNAL);
288 throw wcj;
289 }
290 }
291
292 }