1 25 package org.ofbiz.service.job; 26 27 import java.util.Date ; 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 42 public class JobInvoker implements Runnable { 43 44 public static final String 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 thread = null; 50 private Date created = null; 51 private String 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 (); 66 this.run = true; 67 this.count = 0; 68 this.jp = jp; 69 this.wait = wait; 70 71 this.thread = new Thread (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 87 public void stop() { 88 run = false; 89 } 90 91 94 public void wakeUp() { 95 notifyAll(); 96 } 97 98 102 public int getUsage() { 103 return count; 104 } 105 106 110 public long getTime() { 111 return created.getTime(); 112 } 113 114 118 public String getName() { 119 return this.name; 120 } 121 122 126 public int getCurrentStatus() { 127 return this.statusCode; 128 } 129 130 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 147 public String 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 163 public String 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 179 public String getServiceName() { 180 String 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 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 ie) { 214 Debug.logError(ie, "JobInvoker.run() : InterruptedException", module); 215 stop(); 216 } 217 } else { 218 this.currentJob = job; 220 this.statusCode = 1; 221 this.jobStart = System.currentTimeMillis(); 222 223 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 this.currentJob = null; 234 this.statusCode = 0; 235 this.jobStart = 0; 236 237 try { 239 if (TransactionUtil.isTransactionInPlace()) { 241 Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module); 242 TransactionUtil.rollback(); 243 } 244 245 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 count++; 256 if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " (" + count + ") total.", module); 257 } 258 long diff = (new Date ().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 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 |