KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > service > job > JobInvoker


1 /*
2  * $Id: JobInvoker.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */

25 package org.ofbiz.service.job;
26
27 import java.util.Date JavaDoc;
28
29 import org.ofbiz.service.config.ServiceConfigUtil;
30 import org.ofbiz.base.util.Debug;
31 import org.ofbiz.base.util.UtilDateTime;
32 import org.ofbiz.entity.transaction.TransactionUtil;
33 import org.ofbiz.entity.transaction.GenericTransactionException;
34
35 /**
36  * JobInvoker
37  *
38  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
39  * @version $Rev: 5462 $
40  * @since 2.0
41  */

42 public class JobInvoker implements Runnable JavaDoc {
43
44     public static final String JavaDoc module = JobInvoker.class.getName();
45     public static final long THREAD_TTL = 18000000;
46     public static final int WAIT_TIME = 750;
47
48     private JobPoller jp = null;
49     private Thread JavaDoc thread = null;
50     private Date JavaDoc created = null;
51     private String JavaDoc name = null;
52     private int count = 0;
53     private int wait = 0;
54
55     private volatile boolean run = false;
56     private volatile Job currentJob = null;
57     private volatile int statusCode = 0;
58     private volatile long jobStart = 0;
59
60     public JobInvoker(JobPoller jp) {
61         this(jp, WAIT_TIME);
62     }
63
64     public JobInvoker(JobPoller jp, int wait) {
65         this.created = new Date JavaDoc();
66         this.run = true;
67         this.count = 0;
68         this.jp = jp;
69         this.wait = wait;
70
71         // get a new thread
72
this.thread = new Thread JavaDoc(this);
73         this.name = "invoker-" + this.thread.getName();
74
75         this.thread.setDaemon(false);
76         this.thread.setName(this.name);
77
78         if (Debug.verboseOn()) Debug.logVerbose("JobInoker: Starting Invoker Thread -- " + thread.getName(), module);
79         this.thread.start();
80     }
81
82     protected JobInvoker() {}
83
84     /**
85      * Tells the thread to stop after the next job.
86      */

87     public void stop() {
88         run = false;
89     }
90
91     /**
92      * Wakes up this thread.
93      */

94     public void wakeUp() {
95         notifyAll();
96     }
97
98     /**
99      * Gets the number of times this thread was used.
100      * @return The number of times used.
101      */

102     public int getUsage() {
103         return count;
104     }
105
106     /**
107      * Gets the time when this thread was created.
108      * @return Time in milliseconds when this was created.
109      */

110     public long getTime() {
111         return created.getTime();
112     }
113
114     /**
115      * Gets the name of this JobInvoker.
116      * @return Name of the invoker.
117      */

118     public String JavaDoc getName() {
119         return this.name;
120     }
121
122     /**
123      * Gets the status code for this thread (0 = sleeping, 1 = running job)
124      * @return 0 for sleeping or 1 when running a job.
125      */

126     public int getCurrentStatus() {
127         return this.statusCode;
128     }
129
130     /**
131      * Gets the total time the current job has been running or 0 when sleeping.
132      * @return Total time the curent job has been running.
133      */

134     public long getCurrentRuntime() {
135         if (this.jobStart > 0) {
136             long now = System.currentTimeMillis();
137             return now - this.jobStart;
138         } else {
139             return 0;
140         }
141     }
142
143     /**
144      * Get the current running job's ID.
145      * @return String ID of the current running job.
146      */

147     public String JavaDoc getJobId() {
148         if (this.statusCode == 1) {
149             if (this.currentJob != null) {
150                 return this.currentJob.getJobId();
151             } else {
152                 return "WARNING: Invalid Job!";
153             }
154         } else {
155             return null;
156         }
157     }
158
159     /**
160      * Get the current running job's name.
161      * @return String name of the current running job.
162      */

163     public String JavaDoc getJobName() {
164         if (this.statusCode == 1) {
165             if (this.currentJob != null) {
166                 return this.currentJob.getJobName();
167             } else {
168                 return "WARNING: Invalid Job!";
169             }
170         } else {
171             return null;
172         }
173     }
174
175     /**
176      * Returns the name of the service being run.
177      * @return The name of the service being run.
178      */

179     public String JavaDoc getServiceName() {
180         String JavaDoc serviceName = null;
181         if (this.statusCode == 1) {
182             if (this.currentJob != null) {
183                 if (this.currentJob instanceof GenericServiceJob) {
184                     GenericServiceJob gsj = (GenericServiceJob) this.currentJob;
185                     try {
186                         serviceName = gsj.getServiceName();
187                     } catch (InvalidJobException e) {
188                         Debug.logError(e, module);
189                     }
190                 }
191             }
192         }
193         return serviceName;
194     }
195
196     /**
197      * Kill this invoker thread.s
198      */

199     public void kill() {
200         this.stop();
201         this.statusCode = -1;
202         this.thread.interrupt();
203         this.thread = null;
204     }
205
206     public synchronized void run() {
207         while (run) {
208             Job job = jp.next();
209
210             if (job == null) {
211                 try {
212                     wait(wait);
213                 } catch (InterruptedException JavaDoc ie) {
214                     Debug.logError(ie, "JobInvoker.run() : InterruptedException", module);
215                     stop();
216                 }
217             } else {
218                 // setup the current job settings
219
this.currentJob = job;
220                 this.statusCode = 1;
221                 this.jobStart = System.currentTimeMillis();
222
223                 // execute the job
224
if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " executing job -- " + job.getJobName(), module);
225                 try {
226                     job.exec();
227                 } catch (InvalidJobException e) {
228                     Debug.logWarning(e.getMessage(), module);
229                 }
230                 if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " finished executing job -- " + job.getJobName(), module);
231
232                 // clear the current job settings
233
this.currentJob = null;
234                 this.statusCode = 0;
235                 this.jobStart = 0;
236
237                 // sanity check; make sure we don't have any transactions in place
238
try {
239                     // roll back current TX first
240
if (TransactionUtil.isTransactionInPlace()) {
241                         Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module);
242                         TransactionUtil.rollback();
243                     }
244
245                     // now resume/rollback any suspended txs
246
if (TransactionUtil.suspendedTransactionsHeld()) {
247                         int suspended = TransactionUtil.cleanSuspendedTransactions();
248                         Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module);
249                     }
250                 } catch (GenericTransactionException e) {
251                     Debug.logWarning(e, module);
252                 }
253
254                 // increment the count
255
count++;
256                 if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " (" + count + ") total.", module);
257             }
258             long diff = (new Date JavaDoc().getTime() - this.getTime());
259
260             if (getTTL() > 0 && diff > getTTL())
261                 jp.removeThread(this);
262         }
263         if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " dead -- " + UtilDateTime.nowTimestamp(), module);
264     }
265
266     private long getTTL() {
267         long ttl = THREAD_TTL;
268
269         try {
270             ttl = Long.parseLong(ServiceConfigUtil.getElementAttr("thread-pool", "ttl"));
271         } catch (NumberFormatException JavaDoc nfe) {
272             Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.", module);
273         }
274         return ttl;
275     }
276 }
277
Popular Tags