You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Jacques Le Roux <ja...@les7arts.com> on 2012/08/04 12:21:05 UTC
Re: svn commit: r1362422 - in /ofbiz/trunk/framework: service/config/ service/dtd/ service/src/org/ofbiz/service/job/ webtools/webapp/webtools/WEB-INF/actions/service/ webtools/widget/
Hi,
While reviewing Eclipse found that JobPoller misses some Map and List types arguments
Eclipse autocompletion suggests the following change:
Index: framework/service/src/org/ofbiz/service/job/JobPoller.java
===================================================================
--- framework/service/src/org/ofbiz/service/job/JobPoller.java (revision 1369293)
+++ framework/service/src/org/ofbiz/service/job/JobPoller.java (working copy)
@@ -83,7 +83,7 @@
}
public Map<String, Object> getPoolState() {
- Map poolState = new HashMap();
+ Map<String, Object> poolState = new HashMap<String, Object>();
poolState.put("pollerName", this.name);
poolState.put("pollerThreadName", "OFBiz-JobPoller-" + this.name);
poolState.put("invokerThreadNameFormat", "OFBiz-JobInvoker-" + this.name + "-<SEQ>");
@@ -95,12 +95,12 @@
poolState.put("greatestNumberOfInvokerThreads", this.executor.getLargestPoolSize());
poolState.put("numberOfCompletedTasks", this.executor.getCompletedTaskCount());
BlockingQueue<Runnable> queue = this.executor.getQueue();
- List taskList = new ArrayList();
- Map taskInfo = null;
+ List<Map> taskList = new ArrayList<Map>();
+ Map<String, Comparable> taskInfo = null;
for (Runnable task : queue) {
if (task instanceof JobInvoker) {
JobInvoker jobInvoker = (JobInvoker) task;
- taskInfo = new HashMap();
+ taskInfo = new HashMap<String, Comparable>();
taskInfo.put("id", jobInvoker.getJobId());
taskInfo.put("name", jobInvoker.getJobName());
taskInfo.put("serviceName", jobInvoker.getServiceName());
Methods like executor.getCorePoolSize() return int/s and methods like jobInvoker.getTime() return long/s. It should be ok, thanks to
autoboxing, and it compiles of course.
But I wonder why Jacopo did not do it, any reasons or just a miss?
Jacques
From: <ja...@apache.org>
> Author: jacopoc
> Date: Tue Jul 17 09:20:42 2012
> New Revision: 1362422
>
> URL: http://svn.apache.org/viewvc?rev=1362422&view=rev
> Log:
> Refactored the very old code in the org.ofbiz.service.job package to leverage the Executor framework of java.util.concurrent
> rather than relying on ad-hoc synchronization and thread management: the new code is simpler, smaller and it is now easier to
> review and change the execution policy; two attributes of service-config.xsd have been deprecated as they are not used in the new
> version ("jobs" and "wait-millis").
>
> Added:
> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
> Modified:
> ofbiz/trunk/framework/service/config/serviceengine.xml
> ofbiz/trunk/framework/service/dtd/service-config.xsd
> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java
> ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
> ofbiz/trunk/framework/webtools/widget/ServiceForms.xml
> ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml
>
> Modified: ofbiz/trunk/framework/service/config/serviceengine.xml
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/serviceengine.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/service/config/serviceengine.xml (original)
> +++ ofbiz/trunk/framework/service/config/serviceengine.xml Tue Jul 17 09:20:42 2012
> @@ -30,8 +30,6 @@ under the License.
> purge-job-days="4"
> failed-retry-min="3"
> ttl="18000000"
> - wait-millis="750"
> - jobs="10"
> min-threads="5"
> max-threads="15"
> poll-enabled="true"
>
> Modified: ofbiz/trunk/framework/service/dtd/service-config.xsd
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/dtd/service-config.xsd?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/service/dtd/service-config.xsd (original)
> +++ ofbiz/trunk/framework/service/dtd/service-config.xsd Tue Jul 17 09:20:42 2012
> @@ -68,8 +68,8 @@ under the License.
> <xs:attribute type="xs:nonNegativeInteger" name="purge-job-days" default="30"/>
> <xs:attribute type="xs:nonNegativeInteger" name="failed-retry-min" default="30"/>
> <xs:attribute type="xs:nonNegativeInteger" name="ttl" use="required"/>
> - <xs:attribute type="xs:nonNegativeInteger" name="wait-millis" use="required"/>
> - <xs:attribute type="xs:nonNegativeInteger" name="jobs" use="required"/>
> + <xs:attribute type="xs:nonNegativeInteger" name="wait-millis"/> <!-- deprecated -->
> + <xs:attribute type="xs:nonNegativeInteger" name="jobs"/> <!-- deprecated -->
> <xs:attribute type="xs:nonNegativeInteger" name="min-threads" use="required"/>
> <xs:attribute type="xs:nonNegativeInteger" name="max-threads" use="required"/>
> <xs:attribute name="poll-enabled" default="true">
>
> Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java (original)
> +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java Tue Jul 17 09:20:42 2012
> @@ -20,12 +20,9 @@ package org.ofbiz.service.job;
>
> import java.util.Date;
>
> -import org.apache.commons.lang.math.NumberUtils;
> import org.ofbiz.base.util.Debug;
> -import org.ofbiz.base.util.UtilDateTime;
> import org.ofbiz.entity.transaction.GenericTransactionException;
> import org.ofbiz.entity.transaction.TransactionUtil;
> -import org.ofbiz.service.config.ServiceConfigUtil;
>
> /**
> * JobInvoker
> @@ -33,82 +30,20 @@ import org.ofbiz.service.config.ServiceC
> public class JobInvoker implements Runnable {
>
> public static final String module = JobInvoker.class.getName();
> - public static final long THREAD_TTL = 18000000;
> - public static final int WAIT_TIME = 750;
>
> - private JobPoller jp = null;
> - private Thread thread = null;
> private Date created = null;
> - private String name = null;
> - private int count = 0;
> - private int wait = 0;
> -
> - private volatile boolean run = false;
> - private volatile Job currentJob = null;
> - private volatile int statusCode = 0;
> - private volatile long jobStart = 0;
> + private long jobStart;
>
> - public JobInvoker(JobPoller jp) {
> - this(jp, WAIT_TIME);
> - }
> + private Job currentJob = null;
>
> - public JobInvoker(JobPoller jp, int wait) {
> + public JobInvoker(Job job) {
> this.created = new Date();
> - this.run = true;
> - this.count = 0;
> - this.jp = jp;
> - this.wait = wait;
> -
> - // service dispatcher delegator name (for thread name)
> - String delegatorName = jp.getManager().getDelegator().getDelegatorName();
> -
> - // get a new thread
> - this.thread = new Thread(this);
> - this.name = delegatorName + "-invoker-" + this.thread.getName();
> -
> - this.thread.setDaemon(false);
> - this.thread.setName(this.name);
> -
> - if (Debug.verboseOn()) Debug.logVerbose("JobInvoker: Starting Invoker Thread -- " + thread.getName(), module);
> - this.thread.start();
> + this.currentJob = job;
> }
>
> protected JobInvoker() {}
>
> /**
> - * Tells the thread to stop after the next job.
> - */
> - public void stop() {
> - run = false;
> - }
> -
> - /**
> - * Wakes up this thread.
> - */
> - public void wakeUp() {
> - notifyAll();
> - }
> -
> - /**
> - * Gets the number of times this thread was used.
> - * @return The number of times used.
> - */
> - public int getUsage() {
> - return count;
> - }
> -
> - /**
> - * Gets the remaining time this thread has before it is killed
> - * @return Time in millis remaining
> - */
> - public long getTimeRemaining() {
> - long now = UtilDateTime.nowTimestamp().getTime();
> - long time = getTime();
> - long ttl = getTTL();
> - return (time + ttl) - now;
> - }
> -
> - /**
> * Gets the time when this thread was created.
> * @return Time in milliseconds when this was created.
> */
> @@ -117,24 +52,8 @@ public class JobInvoker implements Runna
> }
>
> /**
> - * Gets the name of this JobInvoker.
> - * @return Name of the invoker.
> - */
> - public String getName() {
> - return this.name;
> - }
> -
> - /**
> - * Gets the status code for this thread (0 = sleeping, 1 = running job)
> - * @return 0 for sleeping or 1 when running a job.
> - */
> - public int getCurrentStatus() {
> - return this.statusCode;
> - }
> -
> - /**
> * Gets the total time the current job has been running or 0 when sleeping.
> - * @return Total time the curent job has been running.
> + * @return Total time the current job has been running.
> */
> public long getCurrentRuntime() {
> if (this.jobStart > 0) {
> @@ -145,27 +64,15 @@ public class JobInvoker implements Runna
> }
> }
>
> - public Long getThreadId() {
> - if (this.thread != null) {
> - return this.thread.getId();
> - } else {
> - return null;
> - }
> - }
> -
> /**
> * Get the current running job's ID.
> * @return String ID of the current running job.
> */
> public String getJobId() {
> - if (this.statusCode == 1) {
> - if (this.currentJob != null) {
> - return this.currentJob.getJobId();
> - } else {
> - return "WARNING: Invalid Job!";
> - }
> + if (this.currentJob != null) {
> + return this.currentJob.getJobId();
> } else {
> - return null;
> + return "WARNING: Invalid Job!";
> }
> }
>
> @@ -174,14 +81,10 @@ public class JobInvoker implements Runna
> * @return String name of the current running job.
> */
> public String getJobName() {
> - if (this.statusCode == 1) {
> - if (this.currentJob != null) {
> - return this.currentJob.getJobName();
> - } else {
> - return "WARNING: Invalid Job!";
> - }
> + if (this.currentJob != null) {
> + return this.currentJob.getJobName();
> } else {
> - return null;
> + return "WARNING: Invalid Job!";
> }
> }
>
> @@ -191,101 +94,45 @@ public class JobInvoker implements Runna
> */
> public String getServiceName() {
> String serviceName = null;
> - if (this.statusCode == 1) {
> - if (this.currentJob != null) {
> - if (this.currentJob instanceof GenericServiceJob) {
> - GenericServiceJob gsj = (GenericServiceJob) this.currentJob;
> - try {
> - serviceName = gsj.getServiceName();
> - } catch (InvalidJobException e) {
> - Debug.logError(e, module);
> - }
> + if (this.currentJob != null) {
> + if (this.currentJob instanceof GenericServiceJob) {
> + GenericServiceJob gsj = (GenericServiceJob) this.currentJob;
> + try {
> + serviceName = gsj.getServiceName();
> + } catch (InvalidJobException e) {
> + Debug.logError(e, module);
> }
> }
> }
> return serviceName;
> }
>
> - /**
> - * Kill this invoker thread.s
> - */
> - public void kill() {
> - this.stop();
> - this.statusCode = -1;
> - this.thread.interrupt();
> - this.thread = null;
> - }
> + public void run() {
> + // setup the current job settings
> + this.jobStart = System.currentTimeMillis();
>
> - public synchronized void run() {
> - while (run) {
> - Job job = jp.next();
> -
> - if (job == null) {
> - try {
> - java.lang.Thread.sleep(wait);
> - } catch (InterruptedException ie) {
> - Debug.logError(ie, "JobInvoker.run() : InterruptedException", module);
> - stop();
> - }
> - } else {
> - Debug.logInfo("Invoker [" + thread.getName() + "] received job [" + job.getJobName() + "] from poller [" +
> jp.toString() + "]", module);
> -
> - // setup the current job settings
> - this.currentJob = job;
> - this.statusCode = 1;
> - this.jobStart = System.currentTimeMillis();
> -
> - // execute the job
> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " executing job -- " + job.getJobName(),
> module);
> - try {
> - job.exec();
> - } catch (InvalidJobException e) {
> - Debug.logWarning(e.getMessage(), module);
> - }
> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " finished executing job -- " +
> job.getJobName(), module);
> -
> - // clear the current job settings
> - this.currentJob = null;
> - this.statusCode = 0;
> - this.jobStart = 0;
> -
> - // sanity check; make sure we don't have any transactions in place
> - try {
> - // roll back current TX first
> - if (TransactionUtil.isTransactionInPlace()) {
> - Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module);
> - TransactionUtil.rollback();
> - }
> -
> - // now resume/rollback any suspended txs
> - if (TransactionUtil.suspendedTransactionsHeld()) {
> - int suspended = TransactionUtil.cleanSuspendedTransactions();
> - Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module);
> - }
> - } catch (GenericTransactionException e) {
> - Debug.logWarning(e, module);
> - }
> -
> - // increment the count
> - count++;
> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " (" + count + ") total.", module);
> - }
> - long diff = (new Date().getTime() - this.getTime());
> -
> - if (getTTL() > 0 && diff > getTTL())
> - jp.removeThread(this);
> + // execute the job
> + try {
> + this.currentJob.exec();
> + } catch (InvalidJobException e) {
> + Debug.logWarning(e.getMessage(), module);
> }
> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " + thread.getName() + " dead -- " + UtilDateTime.nowTimestamp(),
> module);
> - }
> -
> - private long getTTL() {
> - long ttl = THREAD_TTL;
>
> + // sanity check; make sure we don't have any transactions in place
> try {
> - ttl = NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool", "ttl"));
> - } catch (NumberFormatException nfe) {
> - Debug.logError("Problems reading value from attribute [ttl] of element [thread-pool] in serviceengine.xml file [" +
> nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module);
> + // roll back current TX first
> + if (TransactionUtil.isTransactionInPlace()) {
> + Debug.logWarning("*** NOTICE: JobInvoker finished w/ a transaction in place! Rolling back.", module);
> + TransactionUtil.rollback();
> + }
> +
> + // now resume/rollback any suspended txs
> + if (TransactionUtil.suspendedTransactionsHeld()) {
> + int suspended = TransactionUtil.cleanSuspendedTransactions();
> + Debug.logWarning("Resumed/Rolled Back [" + suspended + "] transactions.", module);
> + }
> + } catch (GenericTransactionException e) {
> + Debug.logWarning(e, module);
> }
> - return ttl;
> }
> }
>
> Added: ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java?rev=1362422&view=auto
> ==============================================================================
> --- ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java (added)
> +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java Tue Jul 17 09:20:42 2012
> @@ -0,0 +1,29 @@
> +/*******************************************************************************
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *******************************************************************************/
> +package org.ofbiz.service.job;
> +
> +import java.util.concurrent.atomic.AtomicInteger;
> +
> +public class JobInvokerThread extends Thread {
> + private static final AtomicInteger created = new AtomicInteger();
> +
> + public JobInvokerThread(Runnable runnable, String poolName) {
> + super(runnable, "OFBiz-JobInvoker-" + poolName + "-" + created.getAndIncrement());
> + }
> +}
>
> Added: ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java?rev=1362422&view=auto
> ==============================================================================
> --- ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java (added)
> +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java Tue Jul 17 09:20:42 2012
> @@ -0,0 +1,33 @@
> +/*******************************************************************************
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + *******************************************************************************/
> +package org.ofbiz.service.job;
> +
> +import java.util.concurrent.ThreadFactory;
> +
> +public class JobInvokerThreadFactory implements ThreadFactory {
> + private final String poolName;
> +
> + public JobInvokerThreadFactory(String poolName) {
> + this.poolName = poolName;
> + }
> +
> + public Thread newThread(Runnable runnable) {
> + return new JobInvokerThread(runnable, poolName);
> + }
> +}
>
> Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java (original)
> +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java Tue Jul 17 09:20:42 2012
> @@ -423,18 +423,10 @@ public class JobManager {
> }
>
> /**
> - * Kill a JobInvoker Thread.
> - * @param threadName Name of the JobInvoker Thread to kill.
> - */
> - public void killThread(String threadName) {
> - jp.killThread(threadName);
> - }
> -
> - /**
> * Get a List of each threads current state.
> * @return List containing a Map of each thread's state.
> */
> - public List<Map<String, Object>> processList() {
> + public Map<String, Object> getPoolState() {
> return jp.getPoolState();
> }
>
>
> Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java (original)
> +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java Tue Jul 17 09:20:42 2012
> @@ -18,15 +18,20 @@
> *******************************************************************************/
> package org.ofbiz.service.job;
>
> +import java.util.ArrayList;
> +import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> -
> -import javolution.util.FastList;
> -import javolution.util.FastMap;
> +import java.util.concurrent.BlockingQueue;
> +import java.util.concurrent.LinkedBlockingQueue;
> +import java.util.concurrent.ThreadPoolExecutor;
> +import java.util.concurrent.TimeUnit;
>
> import org.ofbiz.base.util.Debug;
> import org.ofbiz.service.config.ServiceConfigUtil;
>
> +import org.apache.commons.lang.math.NumberUtils;
> +
> /**
> * JobPoller - Polls for persisted jobs to run.
> */
> @@ -36,27 +41,28 @@ public class JobPoller implements Runnab
>
> public static final int MIN_THREADS = 1;
> public static final int MAX_THREADS = 15;
> - public static final int MAX_JOBS = 3;
> public static final int POLL_WAIT = 20000;
> - //public static final long MAX_TTL = 18000000;
> + public static final long THREAD_TTL = 18000000;
>
> - protected Thread thread = null;
> - protected List<JobInvoker> pool = null;
> - protected List<Job> run = null;
> - protected JobManager jm = null;
> -
> - protected volatile boolean isRunning = false;
> + private Thread thread = null;
> + private JobManager jm = null;
> + private ThreadPoolExecutor executor = null;
> + private String name = null;
>
> /**
> * Creates a new JobScheduler
> * @param jm JobManager associated with this scheduler
> */
> public JobPoller(JobManager jm, boolean enabled) {
> + this.name = (jm.getDelegator() != null? jm.getDelegator().getDelegatorName(): "NA");
> this.jm = jm;
> - this.run = FastList.newInstance();
> -
> - // create the thread pool
> - this.pool = createThreadPool();
> + this.executor = new ThreadPoolExecutor(minThreads(),
> + maxThreads(),
> + getTTL(),
> + TimeUnit.MILLISECONDS,
> + new LinkedBlockingQueue<Runnable>(),
> + new JobInvokerThreadFactory(this.name),
> + new ThreadPoolExecutor.AbortPolicy());
>
> if (enabled) {
> // re-load crashed jobs
> @@ -66,11 +72,10 @@ public class JobPoller implements Runnab
> if (pollEnabled()) {
>
> // create the poller thread
> - thread = new Thread(this, this.toString());
> + thread = new Thread(this, "OFBiz-JobPoller-" + this.name);
> thread.setDaemon(false);
>
> // start the poller
> - this.isRunning = true;
> thread.start();
> }
> }
> @@ -84,7 +89,7 @@ public class JobPoller implements Runnab
> java.lang.Thread.sleep(30000);
> } catch (InterruptedException e) {
> }
> - while (isRunning) {
> + while (!executor.isShutdown()) {
> try {
> // grab a list of jobs to run.
> List<Job> pollList = jm.poll();
> @@ -106,140 +111,77 @@ public class JobPoller implements Runnab
> }
>
> /**
> - * Returns the JobManager
> + * Adds a job to the RUN queue
> */
> - public JobManager getManager() {
> - return jm;
> + public void queueNow(Job job) {
> + this.executor.execute(new JobInvoker(job));
> }
>
> /**
> * Stops the JobPoller
> */
> - public void stop() {
> - isRunning = false;
> - destroyThreadPool();
> - }
> -
> - public List<Map<String, Object>> getPoolState() {
> - List<Map<String, Object>> stateList = FastList.newInstance();
> - for (JobInvoker invoker: this.pool) {
> - Map<String, Object> stateMap = FastMap.newInstance();
> - stateMap.put("threadName", invoker.getName());
> - stateMap.put("threadId", invoker.getThreadId());
> - stateMap.put("jobName", invoker.getJobName());
> - stateMap.put("serviceName", invoker.getServiceName());
> - stateMap.put("usage", invoker.getUsage());
> - stateMap.put("ttl", invoker.getTimeRemaining());
> - stateMap.put("runTime", invoker.getCurrentRuntime());
> - stateMap.put("status", invoker.getCurrentStatus());
> - stateList.add(stateMap);
> - }
> - return stateList;
> - }
> -
> - /**
> - * Stops all threads in the threadPool and clears
> - * the pool as final step.
> - */
> - private void destroyThreadPool() {
> - Debug.logInfo("Destroying thread pool...", module);
> - for (JobInvoker ji: pool) {
> - ji.stop();
> - }
> - pool.clear();
> - }
> -
> - public synchronized void killThread(String threadName) {
> - JobInvoker inv = findThread(threadName);
> - if (inv != null) {
> - inv.kill();
> - this.pool.remove(inv);
> - }
> - }
> -
> - private JobInvoker findThread(String threadName) {
> - for (JobInvoker inv: pool) {
> - if (threadName.equals(inv.getName())) {
> - return inv;
> - }
> - }
> - return null;
> - }
> -
> - /**
> - * Returns the next job to run
> - */
> - public Job next() {
> - if (run.size() > 0) {
> - // NOTE: this syncrhonized isn't really necessary as the only method that calls it is already synchronized (the
> JobInvoker.run method), so this is here as an added protection especially for the case where it might be used differently in the
> future
> - synchronized (run) {
> - // make sure the size is still greater than zero
> - if (run.size() > 0) {
> - return run.remove(0);
> + void stop() {
> + Debug.logInfo("Shutting down thread pool for " + this.name, module);
> + this.executor.shutdown();
> + try {
> + // Wait 60 seconds for existing tasks to terminate
> + if (!this.executor.awaitTermination(60, TimeUnit.SECONDS)) {
> + // abrupt shutdown (cancel currently executing tasks)
> + Debug.logInfo("Attempting abrupt shut down of thread pool for " + this.name, module);
> + this.executor.shutdownNow();
> + // Wait 60 seconds for tasks to respond to being cancelled
> + if (!this.executor.awaitTermination(60, TimeUnit.SECONDS)) {
> + Debug.logWarning("Unable to shutdown the thread pool for " + this.name, module);
> }
> }
> + } catch (InterruptedException ie) {
> + // re cancel if current thread was also interrupted
> + this.executor.shutdownNow();
> + // preserve interrupt status
> + Thread.currentThread().interrupt();
> }
> - return null;
> + Debug.logInfo("Shutdown completed of thread pool for " + this.name, module);
> }
>
> /**
> - * Adds a job to the RUN queue
> + * Returns the JobManager
> */
> - public void queueNow(Job job) {
> - //Debug.logInfo("[" + Thread.currentThread().getId() + "] Begin queueNow; holds run lock? " + Thread.holdsLock(run),
> module);
> -
> - // NOTE DEJ20071201 MUST use a different object for the lock here because the "this" object is always held by the poller
> thread in the run method above (which sleeps and runs)
> - synchronized (run) {
> - run.add(job);
> - }
> - if (Debug.verboseOn()) Debug.logVerbose("New run queue size: " + run.size(), module);
> - if (run.size() > pool.size() && pool.size() < maxThreads()) {
> - synchronized (pool) {
> - if (run.size() > pool.size() && pool.size() < maxThreads()) {
> - int calcSize = (run.size() / jobsPerThread()) - (pool.size());
> - int addSize = calcSize > maxThreads() ? maxThreads() : calcSize;
> -
> - for (int i = 0; i < addSize; i++) {
> - JobInvoker iv = new JobInvoker(this, invokerWaitTime());
> - pool.add(iv);
> - }
> - }
> - }
> - }
> + public JobManager getManager() {
> + return jm;
> }
>
> - /**
> - * Removes a thread from the pool.
> - * @param invoker The invoker to remove.
> - */
> - public void removeThread(JobInvoker invoker) {
> - if (pool != null) {
> - synchronized (pool) {
> - pool.remove(invoker);
> - invoker.stop();
> - }
> - }
> -
> - if (pool != null && pool.size() < minThreads()) {
> - synchronized (pool) {
> - for (int i = 0; i < minThreads() - pool.size(); i++) {
> - JobInvoker iv = new JobInvoker(this, invokerWaitTime());
> - pool.add(iv);
> - }
> + public Map<String, Object> getPoolState() {
> + Map poolState = new HashMap();
> + poolState.put("pollerName", this.name);
> + poolState.put("pollerThreadName", "OFBiz-JobPoller-" + this.name);
> + poolState.put("invokerThreadNameFormat", "OFBiz-JobInvoker-" + this.name + "-<SEQ>");
> + poolState.put("keepAliveTimeInSeconds", this.executor.getKeepAliveTime(TimeUnit.SECONDS));
> +
> + poolState.put("numberOfCoreInvokerThreads", this.executor.getCorePoolSize());
> + poolState.put("currentNumberOfInvokerThreads", this.executor.getPoolSize());
> + poolState.put("numberOfActiveInvokerThreads", this.executor.getActiveCount());
> + poolState.put("maxNumberOfInvokerThreads", this.executor.getMaximumPoolSize());
> + poolState.put("greatestNumberOfInvokerThreads", this.executor.getLargestPoolSize());
> +
> + poolState.put("numberOfCompletedTasks", this.executor.getCompletedTaskCount());
> +
> + BlockingQueue<Runnable> queue = this.executor.getQueue();
> + List taskList = new ArrayList();
> + Map taskInfo = null;
> + for (Runnable task: queue) {
> + if (task instanceof JobInvoker) {
> + JobInvoker jobInvoker = (JobInvoker)task;
> + taskInfo = new HashMap();
> + taskInfo.put("id", jobInvoker.getJobId());
> + taskInfo.put("name", jobInvoker.getJobName());
> + taskInfo.put("serviceName", jobInvoker.getServiceName());
> + taskInfo.put("time", jobInvoker.getTime());
> + taskInfo.put("runtime", jobInvoker.getCurrentRuntime());
> + taskList.add(taskInfo);
> }
> }
> - }
> -
> - // Creates the invoker pool
> - private List<JobInvoker> createThreadPool() {
> - List<JobInvoker> threadPool = FastList.newInstance();
> -
> - while (threadPool.size() < minThreads()) {
> - JobInvoker iv = new JobInvoker(this, invokerWaitTime());
> - threadPool.add(iv);
> - }
> -
> - return threadPool;
> + poolState.put("taskList", taskList);
> + return poolState;
> }
>
> private int maxThreads() {
> @@ -264,37 +206,26 @@ public class JobPoller implements Runnab
> return min;
> }
>
> - private int jobsPerThread() {
> - int jobs = MAX_JOBS;
> -
> - try {
> - jobs = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "jobs"));
> - } catch (NumberFormatException nfe) {
> - Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
> module);
> - }
> - return jobs;
> - }
> -
> - private int invokerWaitTime() {
> - int wait = JobInvoker.WAIT_TIME;
> + private int pollWaitTime() {
> + int poll = POLL_WAIT;
>
> try {
> - wait = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "wait-millis"));
> + poll = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "poll-db-millis"));
> } catch (NumberFormatException nfe) {
> Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
> module);
> }
> - return wait;
> + return poll;
> }
>
> - private int pollWaitTime() {
> - int poll = POLL_WAIT;
> + private long getTTL() {
> + long ttl = THREAD_TTL;
>
> try {
> - poll = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "poll-db-millis"));
> + ttl = NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool", "ttl"));
> } catch (NumberFormatException nfe) {
> - Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
> module);
> + Debug.logError("Problems reading value from attribute [ttl] of element [thread-pool] in serviceengine.xml file [" +
> nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module);
> }
> - return poll;
> + return ttl;
> }
>
> private boolean pollEnabled() {
>
> Modified: ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy (original)
> +++ ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy Tue Jul 17 09:20:42 2012
> @@ -35,19 +35,9 @@ uiLabelMap = UtilProperties.getResourceB
> uiLabelMap.addBottomResourceBundle("CommonUiLabels");
>
> threads = [];
> -jobs = dispatcher.getJobManager().processList();
> -jobs.each { job ->
> - state = job.status;
> - switch (state) {
> - case 0 : status = uiLabelMap.WebtoolsStatusSleeping; break;
> - case 1 : status = uiLabelMap.WebtoolsStatusRunning; break;
> - case -1: status = uiLabelMap.WebtoolsStatusShuttingDown; break;
> - default: status = uiLabelMap.WebtoolsStatusInvalid; break;
> - }
> - job.status = status;
> - threads.add(job);
> -}
> -context.threads = threads;
> +poolState = dispatcher.getJobManager().getPoolState();
> +context.poolState = poolState;
> +context.threads = poolState.taskList;
>
> // Some stuff for general threads on the server
> currentThread = Thread.currentThread();
>
> Modified: ofbiz/trunk/framework/webtools/widget/ServiceForms.xml
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/ServiceForms.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/webtools/widget/ServiceForms.xml (original)
> +++ ofbiz/trunk/framework/webtools/widget/ServiceForms.xml Tue Jul 17 09:20:42 2012
> @@ -110,14 +110,24 @@ under the License.
> <field name="key"><display/></field>
> <field name="value"><display/></field>
> </form>
> + <form name="PoolState" type="single" default-map-name="poolState">
> + <field name="pollerName"><display/></field>
> + <field name="pollerThreadName"><display/></field>
> + <field name="invokerThreadNameFormat"><display/></field>
> + <field name="keepAliveTimeInSeconds"><display/></field>
> + <field name="numberOfCoreInvokerThreads"><display/></field>
> + <field name="currentNumberOfInvokerThreads"><display/></field>
> + <field name="numberOfActiveInvokerThreads"><display/></field>
> + <field name="maxNumberOfInvokerThreads"><display/></field>
> + <field name="greatestNumberOfInvokerThreads"><display/></field>
> + <field name="numberOfCompletedTasks"><display/></field>
> + </form>
> <form name="ListJavaThread" type="list" list-name="threads" paginate-target="threadList" separate-columns="true"
> odd-row-style="alternate-row" default-table-style="basic-table hover-bar">
> - <field name="threadId" title="${uiLabelMap.WebtoolsThread}"><display description="${threadId} ${threadName}"/></field>
> - <field name="status" title="${uiLabelMap.CommonStatus}"><display/></field>
> - <field name="jobName" title="${uiLabelMap.WebtoolsJob}"><display default-value="${uiLabelMap.CommonNone}"/></field>
> + <field name="id" title="${uiLabelMap.WebtoolsThread}"><display description="${threadId} ${threadName}"/></field>
> + <field name="name" title="${uiLabelMap.WebtoolsJob}"><display default-value="${uiLabelMap.CommonNone}"/></field>
> <field name="serviceName" title="${uiLabelMap.WebtoolsService}"><display
> default-value="${uiLabelMap.CommonNone}"/></field>
> - <field name="usage" title="${uiLabelMap.WebtoolsUsage}"><display/></field>
> - <field name="ttl" title="${uiLabelMap.WebtoolsTTL} (ms)"><display/></field>
> + <field name="time"><display/></field>
> <field name="runTime" title="${uiLabelMap.CommonTime} (ms)"><display/></field>
> </form>
> <form name="ListServices" type="list" list-name="services" paginate-target="ServiceLog" separate-columns="true"
>
> Modified: ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml (original)
> +++ ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml Tue Jul 17 09:20:42 2012
> @@ -103,6 +103,7 @@ under the License.
> <decorator-screen name="CommonServiceDecorator" location="${parameters.mainDecoratorLocation}">
> <decorator-section name="body">
> <screenlet title="${uiLabelMap.WebtoolsServiceEngineThreads}">
> + <include-form name="PoolState" location="component://webtools/widget/ServiceForms.xml"/>
> <include-form name="ListJavaThread" location="component://webtools/widget/ServiceForms.xml"/>
> </screenlet>
> <screenlet title="${uiLabelMap.WebtoolsGeneralJavaThreads}">
>
>
Re: svn commit: r1362422 - in /ofbiz/trunk/framework: service/config/
service/dtd/ service/src/org/ofbiz/service/job/ webtools/webapp/webtools/WEB-INF/actions/service/
webtools/widget/
Posted by Adrian Crum <ad...@sandglass-software.com>.
I'm working on the Job Scheduler code right now. I fixed it already.
-Adrian
On 8/4/2012 11:21 AM, Jacques Le Roux wrote:
> Hi,
>
> While reviewing Eclipse found that JobPoller misses some Map and List
> types arguments
> Eclipse autocompletion suggests the following change:
>
> Index: framework/service/src/org/ofbiz/service/job/JobPoller.java
> ===================================================================
> --- framework/service/src/org/ofbiz/service/job/JobPoller.java
> (revision 1369293)
> +++ framework/service/src/org/ofbiz/service/job/JobPoller.java
> (working copy)
> @@ -83,7 +83,7 @@
> }
>
> public Map<String, Object> getPoolState() {
> - Map poolState = new HashMap();
> + Map<String, Object> poolState = new HashMap<String, Object>();
> poolState.put("pollerName", this.name);
> poolState.put("pollerThreadName", "OFBiz-JobPoller-" +
> this.name);
> poolState.put("invokerThreadNameFormat", "OFBiz-JobInvoker-" +
> this.name + "-<SEQ>");
> @@ -95,12 +95,12 @@
> poolState.put("greatestNumberOfInvokerThreads",
> this.executor.getLargestPoolSize());
> poolState.put("numberOfCompletedTasks",
> this.executor.getCompletedTaskCount());
> BlockingQueue<Runnable> queue = this.executor.getQueue();
> - List taskList = new ArrayList();
> - Map taskInfo = null;
> + List<Map> taskList = new ArrayList<Map>();
> + Map<String, Comparable> taskInfo = null;
> for (Runnable task : queue) {
> if (task instanceof JobInvoker) {
> JobInvoker jobInvoker = (JobInvoker) task;
> - taskInfo = new HashMap();
> + taskInfo = new HashMap<String, Comparable>();
> taskInfo.put("id", jobInvoker.getJobId());
> taskInfo.put("name", jobInvoker.getJobName());
> taskInfo.put("serviceName", jobInvoker.getServiceName());
>
> Methods like executor.getCorePoolSize() return int/s and methods like
> jobInvoker.getTime() return long/s. It should be ok, thanks to
> autoboxing, and it compiles of course.
> But I wonder why Jacopo did not do it, any reasons or just a miss?
>
> Jacques
>
> From: <ja...@apache.org>
>> Author: jacopoc
>> Date: Tue Jul 17 09:20:42 2012
>> New Revision: 1362422
>>
>> URL: http://svn.apache.org/viewvc?rev=1362422&view=rev
>> Log:
>> Refactored the very old code in the org.ofbiz.service.job package to
>> leverage the Executor framework of java.util.concurrent rather than
>> relying on ad-hoc synchronization and thread management: the new code
>> is simpler, smaller and it is now easier to review and change the
>> execution policy; two attributes of service-config.xsd have been
>> deprecated as they are not used in the new version ("jobs" and
>> "wait-millis").
>>
>> Added:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
>> Modified:
>> ofbiz/trunk/framework/service/config/serviceengine.xml
>> ofbiz/trunk/framework/service/dtd/service-config.xsd
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java
>> ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
>> ofbiz/trunk/framework/webtools/widget/ServiceForms.xml
>> ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml
>>
>> Modified: ofbiz/trunk/framework/service/config/serviceengine.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/serviceengine.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> --- ofbiz/trunk/framework/service/config/serviceengine.xml (original)
>> +++ ofbiz/trunk/framework/service/config/serviceengine.xml Tue Jul 17
>> 09:20:42 2012
>> @@ -30,8 +30,6 @@ under the License.
>> purge-job-days="4"
>> failed-retry-min="3"
>> ttl="18000000"
>> - wait-millis="750"
>> - jobs="10"
>> min-threads="5"
>> max-threads="15"
>> poll-enabled="true"
>>
>> Modified: ofbiz/trunk/framework/service/dtd/service-config.xsd
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/dtd/service-config.xsd?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> --- ofbiz/trunk/framework/service/dtd/service-config.xsd (original)
>> +++ ofbiz/trunk/framework/service/dtd/service-config.xsd Tue Jul 17
>> 09:20:42 2012
>> @@ -68,8 +68,8 @@ under the License.
>> <xs:attribute type="xs:nonNegativeInteger"
>> name="purge-job-days" default="30"/>
>> <xs:attribute type="xs:nonNegativeInteger"
>> name="failed-retry-min" default="30"/>
>> <xs:attribute type="xs:nonNegativeInteger" name="ttl"
>> use="required"/>
>> - <xs:attribute type="xs:nonNegativeInteger"
>> name="wait-millis" use="required"/>
>> - <xs:attribute type="xs:nonNegativeInteger" name="jobs"
>> use="required"/>
>> + <xs:attribute type="xs:nonNegativeInteger"
>> name="wait-millis"/> <!-- deprecated -->
>> + <xs:attribute type="xs:nonNegativeInteger" name="jobs"/>
>> <!-- deprecated -->
>> <xs:attribute type="xs:nonNegativeInteger" name="min-threads"
>> use="required"/>
>> <xs:attribute type="xs:nonNegativeInteger" name="max-threads"
>> use="required"/>
>> <xs:attribute name="poll-enabled" default="true">
>>
>> Modified:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
>> (original)
>> +++
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvoker.java
>> Tue Jul 17 09:20:42 2012
>> @@ -20,12 +20,9 @@ package org.ofbiz.service.job;
>>
>> import java.util.Date;
>>
>> -import org.apache.commons.lang.math.NumberUtils;
>> import org.ofbiz.base.util.Debug;
>> -import org.ofbiz.base.util.UtilDateTime;
>> import org.ofbiz.entity.transaction.GenericTransactionException;
>> import org.ofbiz.entity.transaction.TransactionUtil;
>> -import org.ofbiz.service.config.ServiceConfigUtil;
>>
>> /**
>> * JobInvoker
>> @@ -33,82 +30,20 @@ import org.ofbiz.service.config.ServiceC
>> public class JobInvoker implements Runnable {
>>
>> public static final String module = JobInvoker.class.getName();
>> - public static final long THREAD_TTL = 18000000;
>> - public static final int WAIT_TIME = 750;
>>
>> - private JobPoller jp = null;
>> - private Thread thread = null;
>> private Date created = null;
>> - private String name = null;
>> - private int count = 0;
>> - private int wait = 0;
>> -
>> - private volatile boolean run = false;
>> - private volatile Job currentJob = null;
>> - private volatile int statusCode = 0;
>> - private volatile long jobStart = 0;
>> + private long jobStart;
>>
>> - public JobInvoker(JobPoller jp) {
>> - this(jp, WAIT_TIME);
>> - }
>> + private Job currentJob = null;
>>
>> - public JobInvoker(JobPoller jp, int wait) {
>> + public JobInvoker(Job job) {
>> this.created = new Date();
>> - this.run = true;
>> - this.count = 0;
>> - this.jp = jp;
>> - this.wait = wait;
>> -
>> - // service dispatcher delegator name (for thread name)
>> - String delegatorName =
>> jp.getManager().getDelegator().getDelegatorName();
>> -
>> - // get a new thread
>> - this.thread = new Thread(this);
>> - this.name = delegatorName + "-invoker-" +
>> this.thread.getName();
>> -
>> - this.thread.setDaemon(false);
>> - this.thread.setName(this.name);
>> -
>> - if (Debug.verboseOn()) Debug.logVerbose("JobInvoker:
>> Starting Invoker Thread -- " + thread.getName(), module);
>> - this.thread.start();
>> + this.currentJob = job;
>> }
>>
>> protected JobInvoker() {}
>>
>> /**
>> - * Tells the thread to stop after the next job.
>> - */
>> - public void stop() {
>> - run = false;
>> - }
>> -
>> - /**
>> - * Wakes up this thread.
>> - */
>> - public void wakeUp() {
>> - notifyAll();
>> - }
>> -
>> - /**
>> - * Gets the number of times this thread was used.
>> - * @return The number of times used.
>> - */
>> - public int getUsage() {
>> - return count;
>> - }
>> -
>> - /**
>> - * Gets the remaining time this thread has before it is killed
>> - * @return Time in millis remaining
>> - */
>> - public long getTimeRemaining() {
>> - long now = UtilDateTime.nowTimestamp().getTime();
>> - long time = getTime();
>> - long ttl = getTTL();
>> - return (time + ttl) - now;
>> - }
>> -
>> - /**
>> * Gets the time when this thread was created.
>> * @return Time in milliseconds when this was created.
>> */
>> @@ -117,24 +52,8 @@ public class JobInvoker implements Runna
>> }
>>
>> /**
>> - * Gets the name of this JobInvoker.
>> - * @return Name of the invoker.
>> - */
>> - public String getName() {
>> - return this.name;
>> - }
>> -
>> - /**
>> - * Gets the status code for this thread (0 = sleeping, 1 =
>> running job)
>> - * @return 0 for sleeping or 1 when running a job.
>> - */
>> - public int getCurrentStatus() {
>> - return this.statusCode;
>> - }
>> -
>> - /**
>> * Gets the total time the current job has been running or 0 when
>> sleeping.
>> - * @return Total time the curent job has been running.
>> + * @return Total time the current job has been running.
>> */
>> public long getCurrentRuntime() {
>> if (this.jobStart > 0) {
>> @@ -145,27 +64,15 @@ public class JobInvoker implements Runna
>> }
>> }
>>
>> - public Long getThreadId() {
>> - if (this.thread != null) {
>> - return this.thread.getId();
>> - } else {
>> - return null;
>> - }
>> - }
>> -
>> /**
>> * Get the current running job's ID.
>> * @return String ID of the current running job.
>> */
>> public String getJobId() {
>> - if (this.statusCode == 1) {
>> - if (this.currentJob != null) {
>> - return this.currentJob.getJobId();
>> - } else {
>> - return "WARNING: Invalid Job!";
>> - }
>> + if (this.currentJob != null) {
>> + return this.currentJob.getJobId();
>> } else {
>> - return null;
>> + return "WARNING: Invalid Job!";
>> }
>> }
>>
>> @@ -174,14 +81,10 @@ public class JobInvoker implements Runna
>> * @return String name of the current running job.
>> */
>> public String getJobName() {
>> - if (this.statusCode == 1) {
>> - if (this.currentJob != null) {
>> - return this.currentJob.getJobName();
>> - } else {
>> - return "WARNING: Invalid Job!";
>> - }
>> + if (this.currentJob != null) {
>> + return this.currentJob.getJobName();
>> } else {
>> - return null;
>> + return "WARNING: Invalid Job!";
>> }
>> }
>>
>> @@ -191,101 +94,45 @@ public class JobInvoker implements Runna
>> */
>> public String getServiceName() {
>> String serviceName = null;
>> - if (this.statusCode == 1) {
>> - if (this.currentJob != null) {
>> - if (this.currentJob instanceof GenericServiceJob) {
>> - GenericServiceJob gsj = (GenericServiceJob)
>> this.currentJob;
>> - try {
>> - serviceName = gsj.getServiceName();
>> - } catch (InvalidJobException e) {
>> - Debug.logError(e, module);
>> - }
>> + if (this.currentJob != null) {
>> + if (this.currentJob instanceof GenericServiceJob) {
>> + GenericServiceJob gsj = (GenericServiceJob)
>> this.currentJob;
>> + try {
>> + serviceName = gsj.getServiceName();
>> + } catch (InvalidJobException e) {
>> + Debug.logError(e, module);
>> }
>> }
>> }
>> return serviceName;
>> }
>>
>> - /**
>> - * Kill this invoker thread.s
>> - */
>> - public void kill() {
>> - this.stop();
>> - this.statusCode = -1;
>> - this.thread.interrupt();
>> - this.thread = null;
>> - }
>> + public void run() {
>> + // setup the current job settings
>> + this.jobStart = System.currentTimeMillis();
>>
>> - public synchronized void run() {
>> - while (run) {
>> - Job job = jp.next();
>> -
>> - if (job == null) {
>> - try {
>> - java.lang.Thread.sleep(wait);
>> - } catch (InterruptedException ie) {
>> - Debug.logError(ie, "JobInvoker.run() :
>> InterruptedException", module);
>> - stop();
>> - }
>> - } else {
>> - Debug.logInfo("Invoker [" + thread.getName() + "]
>> received job [" + job.getJobName() + "] from poller [" +
>> jp.toString() + "]", module);
>> -
>> - // setup the current job settings
>> - this.currentJob = job;
>> - this.statusCode = 1;
>> - this.jobStart = System.currentTimeMillis();
>> -
>> - // execute the job
>> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: "
>> + thread.getName() + " executing job -- " + job.getJobName(), module);
>> - try {
>> - job.exec();
>> - } catch (InvalidJobException e) {
>> - Debug.logWarning(e.getMessage(), module);
>> - }
>> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: "
>> + thread.getName() + " finished executing job -- " +
>> job.getJobName(), module);
>> -
>> - // clear the current job settings
>> - this.currentJob = null;
>> - this.statusCode = 0;
>> - this.jobStart = 0;
>> -
>> - // sanity check; make sure we don't have any
>> transactions in place
>> - try {
>> - // roll back current TX first
>> - if (TransactionUtil.isTransactionInPlace()) {
>> - Debug.logWarning("*** NOTICE: JobInvoker
>> finished w/ a transaction in place! Rolling back.", module);
>> - TransactionUtil.rollback();
>> - }
>> -
>> - // now resume/rollback any suspended txs
>> - if (TransactionUtil.suspendedTransactionsHeld()) {
>> - int suspended =
>> TransactionUtil.cleanSuspendedTransactions();
>> - Debug.logWarning("Resumed/Rolled Back [" +
>> suspended + "] transactions.", module);
>> - }
>> - } catch (GenericTransactionException e) {
>> - Debug.logWarning(e, module);
>> - }
>> -
>> - // increment the count
>> - count++;
>> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: "
>> + thread.getName() + " (" + count + ") total.", module);
>> - }
>> - long diff = (new Date().getTime() - this.getTime());
>> -
>> - if (getTTL() > 0 && diff > getTTL())
>> - jp.removeThread(this);
>> + // execute the job
>> + try {
>> + this.currentJob.exec();
>> + } catch (InvalidJobException e) {
>> + Debug.logWarning(e.getMessage(), module);
>> }
>> - if (Debug.verboseOn()) Debug.logVerbose("Invoker: " +
>> thread.getName() + " dead -- " + UtilDateTime.nowTimestamp(), module);
>> - }
>> -
>> - private long getTTL() {
>> - long ttl = THREAD_TTL;
>>
>> + // sanity check; make sure we don't have any transactions in
>> place
>> try {
>> - ttl =
>> NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool",
>> "ttl"));
>> - } catch (NumberFormatException nfe) {
>> - Debug.logError("Problems reading value from attribute
>> [ttl] of element [thread-pool] in serviceengine.xml file [" +
>> nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module);
>> + // roll back current TX first
>> + if (TransactionUtil.isTransactionInPlace()) {
>> + Debug.logWarning("*** NOTICE: JobInvoker finished w/
>> a transaction in place! Rolling back.", module);
>> + TransactionUtil.rollback();
>> + }
>> +
>> + // now resume/rollback any suspended txs
>> + if (TransactionUtil.suspendedTransactionsHeld()) {
>> + int suspended =
>> TransactionUtil.cleanSuspendedTransactions();
>> + Debug.logWarning("Resumed/Rolled Back [" + suspended
>> + "] transactions.", module);
>> + }
>> + } catch (GenericTransactionException e) {
>> + Debug.logWarning(e, module);
>> }
>> - return ttl;
>> }
>> }
>>
>> Added:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java?rev=1362422&view=auto
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
>> (added)
>> +++
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThread.java
>> Tue Jul 17 09:20:42 2012
>> @@ -0,0 +1,29 @@
>> +/*******************************************************************************
>>
>> + * Licensed to the Apache Software Foundation (ASF) under one
>> + * or more contributor license agreements. See the NOTICE file
>> + * distributed with this work for additional information
>> + * regarding copyright ownership. The ASF licenses this file
>> + * to you under the Apache License, Version 2.0 (the
>> + * "License"); you may not use this file except in compliance
>> + * with the License. You may obtain a copy of the License at
>> + *
>> + * http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing,
>> + * software distributed under the License is distributed on an
>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>> + * KIND, either express or implied. See the License for the
>> + * specific language governing permissions and limitations
>> + * under the License.
>> +
>> *******************************************************************************/
>> +package org.ofbiz.service.job;
>> +
>> +import java.util.concurrent.atomic.AtomicInteger;
>> +
>> +public class JobInvokerThread extends Thread {
>> + private static final AtomicInteger created = new AtomicInteger();
>> +
>> + public JobInvokerThread(Runnable runnable, String poolName) {
>> + super(runnable, "OFBiz-JobInvoker-" + poolName + "-" +
>> created.getAndIncrement());
>> + }
>> +}
>>
>> Added:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java?rev=1362422&view=auto
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
>> (added)
>> +++
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobInvokerThreadFactory.java
>> Tue Jul 17 09:20:42 2012
>> @@ -0,0 +1,33 @@
>> +/*******************************************************************************
>>
>> + * Licensed to the Apache Software Foundation (ASF) under one
>> + * or more contributor license agreements. See the NOTICE file
>> + * distributed with this work for additional information
>> + * regarding copyright ownership. The ASF licenses this file
>> + * to you under the Apache License, Version 2.0 (the
>> + * "License"); you may not use this file except in compliance
>> + * with the License. You may obtain a copy of the License at
>> + *
>> + * http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing,
>> + * software distributed under the License is distributed on an
>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>> + * KIND, either express or implied. See the License for the
>> + * specific language governing permissions and limitations
>> + * under the License.
>> +
>> *******************************************************************************/
>> +package org.ofbiz.service.job;
>> +
>> +import java.util.concurrent.ThreadFactory;
>> +
>> +public class JobInvokerThreadFactory implements ThreadFactory {
>> + private final String poolName;
>> +
>> + public JobInvokerThreadFactory(String poolName) {
>> + this.poolName = poolName;
>> + }
>> +
>> + public Thread newThread(Runnable runnable) {
>> + return new JobInvokerThread(runnable, poolName);
>> + }
>> +}
>>
>> Modified:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
>> (original)
>> +++
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobManager.java
>> Tue Jul 17 09:20:42 2012
>> @@ -423,18 +423,10 @@ public class JobManager {
>> }
>>
>> /**
>> - * Kill a JobInvoker Thread.
>> - * @param threadName Name of the JobInvoker Thread to kill.
>> - */
>> - public void killThread(String threadName) {
>> - jp.killThread(threadName);
>> - }
>> -
>> - /**
>> * Get a List of each threads current state.
>> * @return List containing a Map of each thread's state.
>> */
>> - public List<Map<String, Object>> processList() {
>> + public Map<String, Object> getPoolState() {
>> return jp.getPoolState();
>> }
>>
>>
>> Modified:
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java (original)
>>
>> +++
>> ofbiz/trunk/framework/service/src/org/ofbiz/service/job/JobPoller.java Tue
>> Jul 17 09:20:42 2012
>> @@ -18,15 +18,20 @@
>> *******************************************************************************/
>>
>> package org.ofbiz.service.job;
>>
>> +import java.util.ArrayList;
>> +import java.util.HashMap;
>> import java.util.List;
>> import java.util.Map;
>> -
>> -import javolution.util.FastList;
>> -import javolution.util.FastMap;
>> +import java.util.concurrent.BlockingQueue;
>> +import java.util.concurrent.LinkedBlockingQueue;
>> +import java.util.concurrent.ThreadPoolExecutor;
>> +import java.util.concurrent.TimeUnit;
>>
>> import org.ofbiz.base.util.Debug;
>> import org.ofbiz.service.config.ServiceConfigUtil;
>>
>> +import org.apache.commons.lang.math.NumberUtils;
>> +
>> /**
>> * JobPoller - Polls for persisted jobs to run.
>> */
>> @@ -36,27 +41,28 @@ public class JobPoller implements Runnab
>>
>> public static final int MIN_THREADS = 1;
>> public static final int MAX_THREADS = 15;
>> - public static final int MAX_JOBS = 3;
>> public static final int POLL_WAIT = 20000;
>> - //public static final long MAX_TTL = 18000000;
>> + public static final long THREAD_TTL = 18000000;
>>
>> - protected Thread thread = null;
>> - protected List<JobInvoker> pool = null;
>> - protected List<Job> run = null;
>> - protected JobManager jm = null;
>> -
>> - protected volatile boolean isRunning = false;
>> + private Thread thread = null;
>> + private JobManager jm = null;
>> + private ThreadPoolExecutor executor = null;
>> + private String name = null;
>>
>> /**
>> * Creates a new JobScheduler
>> * @param jm JobManager associated with this scheduler
>> */
>> public JobPoller(JobManager jm, boolean enabled) {
>> + this.name = (jm.getDelegator() != null?
>> jm.getDelegator().getDelegatorName(): "NA");
>> this.jm = jm;
>> - this.run = FastList.newInstance();
>> -
>> - // create the thread pool
>> - this.pool = createThreadPool();
>> + this.executor = new ThreadPoolExecutor(minThreads(),
>> + maxThreads(),
>> + getTTL(),
>> + TimeUnit.MILLISECONDS,
>> + new
>> LinkedBlockingQueue<Runnable>(),
>> + new
>> JobInvokerThreadFactory(this.name),
>> + new
>> ThreadPoolExecutor.AbortPolicy());
>>
>> if (enabled) {
>> // re-load crashed jobs
>> @@ -66,11 +72,10 @@ public class JobPoller implements Runnab
>> if (pollEnabled()) {
>>
>> // create the poller thread
>> - thread = new Thread(this, this.toString());
>> + thread = new Thread(this, "OFBiz-JobPoller-" +
>> this.name);
>> thread.setDaemon(false);
>>
>> // start the poller
>> - this.isRunning = true;
>> thread.start();
>> }
>> }
>> @@ -84,7 +89,7 @@ public class JobPoller implements Runnab
>> java.lang.Thread.sleep(30000);
>> } catch (InterruptedException e) {
>> }
>> - while (isRunning) {
>> + while (!executor.isShutdown()) {
>> try {
>> // grab a list of jobs to run.
>> List<Job> pollList = jm.poll();
>> @@ -106,140 +111,77 @@ public class JobPoller implements Runnab
>> }
>>
>> /**
>> - * Returns the JobManager
>> + * Adds a job to the RUN queue
>> */
>> - public JobManager getManager() {
>> - return jm;
>> + public void queueNow(Job job) {
>> + this.executor.execute(new JobInvoker(job));
>> }
>>
>> /**
>> * Stops the JobPoller
>> */
>> - public void stop() {
>> - isRunning = false;
>> - destroyThreadPool();
>> - }
>> -
>> - public List<Map<String, Object>> getPoolState() {
>> - List<Map<String, Object>> stateList = FastList.newInstance();
>> - for (JobInvoker invoker: this.pool) {
>> - Map<String, Object> stateMap = FastMap.newInstance();
>> - stateMap.put("threadName", invoker.getName());
>> - stateMap.put("threadId", invoker.getThreadId());
>> - stateMap.put("jobName", invoker.getJobName());
>> - stateMap.put("serviceName", invoker.getServiceName());
>> - stateMap.put("usage", invoker.getUsage());
>> - stateMap.put("ttl", invoker.getTimeRemaining());
>> - stateMap.put("runTime", invoker.getCurrentRuntime());
>> - stateMap.put("status", invoker.getCurrentStatus());
>> - stateList.add(stateMap);
>> - }
>> - return stateList;
>> - }
>> -
>> - /**
>> - * Stops all threads in the threadPool and clears
>> - * the pool as final step.
>> - */
>> - private void destroyThreadPool() {
>> - Debug.logInfo("Destroying thread pool...", module);
>> - for (JobInvoker ji: pool) {
>> - ji.stop();
>> - }
>> - pool.clear();
>> - }
>> -
>> - public synchronized void killThread(String threadName) {
>> - JobInvoker inv = findThread(threadName);
>> - if (inv != null) {
>> - inv.kill();
>> - this.pool.remove(inv);
>> - }
>> - }
>> -
>> - private JobInvoker findThread(String threadName) {
>> - for (JobInvoker inv: pool) {
>> - if (threadName.equals(inv.getName())) {
>> - return inv;
>> - }
>> - }
>> - return null;
>> - }
>> -
>> - /**
>> - * Returns the next job to run
>> - */
>> - public Job next() {
>> - if (run.size() > 0) {
>> - // NOTE: this syncrhonized isn't really necessary as the
>> only method that calls it is already synchronized (the JobInvoker.run
>> method), so this is here as an added protection especially for the
>> case where it might be used differently in the future
>> - synchronized (run) {
>> - // make sure the size is still greater than zero
>> - if (run.size() > 0) {
>> - return run.remove(0);
>> + void stop() {
>> + Debug.logInfo("Shutting down thread pool for " + this.name,
>> module);
>> + this.executor.shutdown();
>> + try {
>> + // Wait 60 seconds for existing tasks to terminate
>> + if (!this.executor.awaitTermination(60,
>> TimeUnit.SECONDS)) {
>> + // abrupt shutdown (cancel currently executing tasks)
>> + Debug.logInfo("Attempting abrupt shut down of thread
>> pool for " + this.name, module);
>> + this.executor.shutdownNow();
>> + // Wait 60 seconds for tasks to respond to being
>> cancelled
>> + if (!this.executor.awaitTermination(60,
>> TimeUnit.SECONDS)) {
>> + Debug.logWarning("Unable to shutdown the thread
>> pool for " + this.name, module);
>> }
>> }
>> + } catch (InterruptedException ie) {
>> + // re cancel if current thread was also interrupted
>> + this.executor.shutdownNow();
>> + // preserve interrupt status
>> + Thread.currentThread().interrupt();
>> }
>> - return null;
>> + Debug.logInfo("Shutdown completed of thread pool for " +
>> this.name, module);
>> }
>>
>> /**
>> - * Adds a job to the RUN queue
>> + * Returns the JobManager
>> */
>> - public void queueNow(Job job) {
>> - //Debug.logInfo("[" + Thread.currentThread().getId() + "]
>> Begin queueNow; holds run lock? " + Thread.holdsLock(run), module);
>> -
>> - // NOTE DEJ20071201 MUST use a different object for the lock
>> here because the "this" object is always held by the poller thread in
>> the run method above (which sleeps and runs)
>> - synchronized (run) {
>> - run.add(job);
>> - }
>> - if (Debug.verboseOn()) Debug.logVerbose("New run queue size:
>> " + run.size(), module);
>> - if (run.size() > pool.size() && pool.size() < maxThreads()) {
>> - synchronized (pool) {
>> - if (run.size() > pool.size() && pool.size() <
>> maxThreads()) {
>> - int calcSize = (run.size() / jobsPerThread()) -
>> (pool.size());
>> - int addSize = calcSize > maxThreads() ?
>> maxThreads() : calcSize;
>> -
>> - for (int i = 0; i < addSize; i++) {
>> - JobInvoker iv = new JobInvoker(this,
>> invokerWaitTime());
>> - pool.add(iv);
>> - }
>> - }
>> - }
>> - }
>> + public JobManager getManager() {
>> + return jm;
>> }
>>
>> - /**
>> - * Removes a thread from the pool.
>> - * @param invoker The invoker to remove.
>> - */
>> - public void removeThread(JobInvoker invoker) {
>> - if (pool != null) {
>> - synchronized (pool) {
>> - pool.remove(invoker);
>> - invoker.stop();
>> - }
>> - }
>> -
>> - if (pool != null && pool.size() < minThreads()) {
>> - synchronized (pool) {
>> - for (int i = 0; i < minThreads() - pool.size(); i++) {
>> - JobInvoker iv = new JobInvoker(this,
>> invokerWaitTime());
>> - pool.add(iv);
>> - }
>> + public Map<String, Object> getPoolState() {
>> + Map poolState = new HashMap();
>> + poolState.put("pollerName", this.name);
>> + poolState.put("pollerThreadName", "OFBiz-JobPoller-" +
>> this.name);
>> + poolState.put("invokerThreadNameFormat", "OFBiz-JobInvoker-"
>> + this.name + "-<SEQ>");
>> + poolState.put("keepAliveTimeInSeconds",
>> this.executor.getKeepAliveTime(TimeUnit.SECONDS));
>> +
>> + poolState.put("numberOfCoreInvokerThreads",
>> this.executor.getCorePoolSize());
>> + poolState.put("currentNumberOfInvokerThreads",
>> this.executor.getPoolSize());
>> + poolState.put("numberOfActiveInvokerThreads",
>> this.executor.getActiveCount());
>> + poolState.put("maxNumberOfInvokerThreads",
>> this.executor.getMaximumPoolSize());
>> + poolState.put("greatestNumberOfInvokerThreads",
>> this.executor.getLargestPoolSize());
>> +
>> + poolState.put("numberOfCompletedTasks",
>> this.executor.getCompletedTaskCount());
>> +
>> + BlockingQueue<Runnable> queue = this.executor.getQueue();
>> + List taskList = new ArrayList();
>> + Map taskInfo = null;
>> + for (Runnable task: queue) {
>> + if (task instanceof JobInvoker) {
>> + JobInvoker jobInvoker = (JobInvoker)task;
>> + taskInfo = new HashMap();
>> + taskInfo.put("id", jobInvoker.getJobId());
>> + taskInfo.put("name", jobInvoker.getJobName());
>> + taskInfo.put("serviceName",
>> jobInvoker.getServiceName());
>> + taskInfo.put("time", jobInvoker.getTime());
>> + taskInfo.put("runtime",
>> jobInvoker.getCurrentRuntime());
>> + taskList.add(taskInfo);
>> }
>> }
>> - }
>> -
>> - // Creates the invoker pool
>> - private List<JobInvoker> createThreadPool() {
>> - List<JobInvoker> threadPool = FastList.newInstance();
>> -
>> - while (threadPool.size() < minThreads()) {
>> - JobInvoker iv = new JobInvoker(this, invokerWaitTime());
>> - threadPool.add(iv);
>> - }
>> -
>> - return threadPool;
>> + poolState.put("taskList", taskList);
>> + return poolState;
>> }
>>
>> private int maxThreads() {
>> @@ -264,37 +206,26 @@ public class JobPoller implements Runnab
>> return min;
>> }
>>
>> - private int jobsPerThread() {
>> - int jobs = MAX_JOBS;
>> -
>> - try {
>> - jobs =
>> Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool",
>> "jobs"));
>> - } catch (NumberFormatException nfe) {
>> - Debug.logError("Problems reading values from
>> serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
>> module);
>> - }
>> - return jobs;
>> - }
>> -
>> - private int invokerWaitTime() {
>> - int wait = JobInvoker.WAIT_TIME;
>> + private int pollWaitTime() {
>> + int poll = POLL_WAIT;
>>
>> try {
>> - wait =
>> Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool",
>> "wait-millis"));
>> + poll =
>> Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool",
>> "poll-db-millis"));
>> } catch (NumberFormatException nfe) {
>> Debug.logError("Problems reading values from
>> serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
>> module);
>> }
>> - return wait;
>> + return poll;
>> }
>>
>> - private int pollWaitTime() {
>> - int poll = POLL_WAIT;
>> + private long getTTL() {
>> + long ttl = THREAD_TTL;
>>
>> try {
>> - poll =
>> Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool",
>> "poll-db-millis"));
>> + ttl =
>> NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool",
>> "ttl"));
>> } catch (NumberFormatException nfe) {
>> - Debug.logError("Problems reading values from
>> serviceengine.xml file [" + nfe.toString() + "]. Using defaults.",
>> module);
>> + Debug.logError("Problems reading value from attribute
>> [ttl] of element [thread-pool] in serviceengine.xml file [" +
>> nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module);
>> }
>> - return poll;
>> + return ttl;
>> }
>>
>> private boolean pollEnabled() {
>>
>> Modified:
>> ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> ---
>> ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
>> (original)
>> +++
>> ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/service/Threads.groovy
>> Tue Jul 17 09:20:42 2012
>> @@ -35,19 +35,9 @@ uiLabelMap = UtilProperties.getResourceB
>> uiLabelMap.addBottomResourceBundle("CommonUiLabels");
>>
>> threads = [];
>> -jobs = dispatcher.getJobManager().processList();
>> -jobs.each { job ->
>> - state = job.status;
>> - switch (state) {
>> - case 0 : status = uiLabelMap.WebtoolsStatusSleeping; break;
>> - case 1 : status = uiLabelMap.WebtoolsStatusRunning; break;
>> - case -1: status = uiLabelMap.WebtoolsStatusShuttingDown; break;
>> - default: status = uiLabelMap.WebtoolsStatusInvalid; break;
>> - }
>> - job.status = status;
>> - threads.add(job);
>> -}
>> -context.threads = threads;
>> +poolState = dispatcher.getJobManager().getPoolState();
>> +context.poolState = poolState;
>> +context.threads = poolState.taskList;
>>
>> // Some stuff for general threads on the server
>> currentThread = Thread.currentThread();
>>
>> Modified: ofbiz/trunk/framework/webtools/widget/ServiceForms.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/ServiceForms.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> --- ofbiz/trunk/framework/webtools/widget/ServiceForms.xml (original)
>> +++ ofbiz/trunk/framework/webtools/widget/ServiceForms.xml Tue Jul 17
>> 09:20:42 2012
>> @@ -110,14 +110,24 @@ under the License.
>> <field name="key"><display/></field>
>> <field name="value"><display/></field>
>> </form>
>> + <form name="PoolState" type="single" default-map-name="poolState">
>> + <field name="pollerName"><display/></field>
>> + <field name="pollerThreadName"><display/></field>
>> + <field name="invokerThreadNameFormat"><display/></field>
>> + <field name="keepAliveTimeInSeconds"><display/></field>
>> + <field name="numberOfCoreInvokerThreads"><display/></field>
>> + <field name="currentNumberOfInvokerThreads"><display/></field>
>> + <field name="numberOfActiveInvokerThreads"><display/></field>
>> + <field name="maxNumberOfInvokerThreads"><display/></field>
>> + <field name="greatestNumberOfInvokerThreads"><display/></field>
>> + <field name="numberOfCompletedTasks"><display/></field>
>> + </form>
>> <form name="ListJavaThread" type="list" list-name="threads"
>> paginate-target="threadList" separate-columns="true"
>> odd-row-style="alternate-row"
>> default-table-style="basic-table hover-bar">
>> - <field name="threadId"
>> title="${uiLabelMap.WebtoolsThread}"><display
>> description="${threadId} ${threadName}"/></field>
>> - <field name="status"
>> title="${uiLabelMap.CommonStatus}"><display/></field>
>> - <field name="jobName"
>> title="${uiLabelMap.WebtoolsJob}"><display
>> default-value="${uiLabelMap.CommonNone}"/></field>
>> + <field name="id"
>> title="${uiLabelMap.WebtoolsThread}"><display
>> description="${threadId} ${threadName}"/></field>
>> + <field name="name"
>> title="${uiLabelMap.WebtoolsJob}"><display
>> default-value="${uiLabelMap.CommonNone}"/></field>
>> <field name="serviceName"
>> title="${uiLabelMap.WebtoolsService}"><display
>> default-value="${uiLabelMap.CommonNone}"/></field>
>> - <field name="usage"
>> title="${uiLabelMap.WebtoolsUsage}"><display/></field>
>> - <field name="ttl" title="${uiLabelMap.WebtoolsTTL}
>> (ms)"><display/></field>
>> + <field name="time"><display/></field>
>> <field name="runTime" title="${uiLabelMap.CommonTime}
>> (ms)"><display/></field>
>> </form>
>> <form name="ListServices" type="list" list-name="services"
>> paginate-target="ServiceLog" separate-columns="true"
>>
>> Modified: ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml
>> URL:
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml?rev=1362422&r1=1362421&r2=1362422&view=diff
>> ==============================================================================
>>
>> --- ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml (original)
>> +++ ofbiz/trunk/framework/webtools/widget/ServiceScreens.xml Tue Jul
>> 17 09:20:42 2012
>> @@ -103,6 +103,7 @@ under the License.
>> <decorator-screen name="CommonServiceDecorator"
>> location="${parameters.mainDecoratorLocation}">
>> <decorator-section name="body">
>> <screenlet
>> title="${uiLabelMap.WebtoolsServiceEngineThreads}">
>> + <include-form name="PoolState"
>> location="component://webtools/widget/ServiceForms.xml"/>
>> <include-form name="ListJavaThread"
>> location="component://webtools/widget/ServiceForms.xml"/>
>> </screenlet>
>> <screenlet
>> title="${uiLabelMap.WebtoolsGeneralJavaThreads}">
>>
>>