You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ch...@apache.org on 2003/11/16 23:42:20 UTC
cvs commit: incubator-geronimo/modules/core/src/test/org/apache/geronimo/connector/work PooledWorkManagerTest.java
chirino 2003/11/16 14:42:20
Added: modules/core/src/deploy workmanager-service.xml
modules/core/src/java/org/apache/geronimo/connector/work
GeronimoWorkManager.java WorkManagerUtil.java
WorkerContext.java
modules/core/src/java/org/apache/geronimo/connector/work/pool
AbstractWorkExecutorPool.java
ScheduleWorkExecutorPool.java
StartWorkExecutorPool.java
SyncWorkExecutorPool.java
TimedOutPooledExecutor.java WorkExecutorPool.java
modules/core/src/test/org/apache/geronimo/connector/work
PooledWorkManagerTest.java
Log:
PR: GERONIMO-73
Submitted by: Gianny DAMOUR
This is the submited patch converted over to use GeronimoMBean for lifecycle managment and placed under the o.a.g.connector.work package.
Revision Changes Path
1.1 incubator-geronimo/modules/core/src/deploy/workmanager-service.xml
Index: workmanager-service.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<components>
<class-space name="geronimo.system:role=ClassSpace,name=System"/>
<!-- ============================================================ -->
<!-- Starts the Work Manager -->
<!-- ============================================================ -->
<mbean descriptor="org.apache.geronimo.connector.work.GeronimoWorkManager"
name="geronimo.jca:role=WorkManager">
</mbean>
<!-- ============================================================ -->
<!-- Starts the Work Executor Pool in charge of the treatment of -->
<!-- synchronous works -->
<!-- ============================================================ -->
<mbean descriptor="org.apache.geronimo.connector.work.pool.SyncWorkExecutorPool"
name="geronimo.jca:role=SynchWorkExecutorPool">
<constructor>
<arg type="int">1</arg>
<arg type="int">1</arg>
</constructor>
</mbean>
<!-- ============================================================ -->
<!-- Starts the Work Executor Pool in charge of the treatment of -->
<!-- synchronous works until the work start. -->
<!-- ============================================================ -->
<mbean descriptor="org.apache.geronimo.connector.work.pool.StartWorkExecutorPool"
name="geronimo.jca:role=StartWorkExecutorPool">
<constructor>
<arg type="int">1</arg>
<arg type="int">1</arg>
</constructor>
</mbean>
<!-- ============================================================ -->
<!-- Starts the Work Executor Pool in charge of the treatment of -->
<!-- asynchronous works. -->
<!-- ============================================================ -->
<mbean descriptor="org.apache.geronimo.connector.work.pool.ScheduleWorkExecutorPool"
name="geronimo.jca:role=ScheduleWorkExecutorPool">
<constructor>
<arg type="int">1</arg>
<arg type="int">1</arg>
</constructor>
</mbean>
</components>
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/GeronimoWorkManager.java
Index: GeronimoWorkManager.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work;
import javax.management.MBeanOperationInfo;
import javax.resource.spi.work.ExecutionContext;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkListener;
import javax.resource.spi.work.WorkManager;
import javax.resource.spi.work.WorkRejectedException;
import org.apache.geronimo.kernel.management.State;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanTarget;
import org.apache.geronimo.kernel.service.GeronimoOperationInfo;
import org.apache.geronimo.kernel.service.GeronimoParameterInfo;
import org.apache.geronimo.connector.work.pool.WorkExecutorPool;
/**
* WorkManager implementation which uses under the cover three WorkExecutorPool
* - one for each synchronization policy - in order to dispatch the submitted
* Work instances.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class GeronimoWorkManager implements WorkManager, GeronimoMBeanTarget {
/**
* Pool of threads used by this WorkManager in order to process
* synchronously the submitted Work instances
*/
private WorkExecutorPool m_syncWorkExecutorPool;
/**
* Pool of threads used by this WorkManager in order to process
* the Work instances submitted via the startWork methods.
*/
private WorkExecutorPool m_startWorkExecutorPool;
/**
* Pool of threads used by this WorkManager in order to process
* scheduled Work instances
*/
private WorkExecutorPool m_scheduledWorkExecutorPool;
private GeronimoMBeanContext geronimoMBeanContext;
/**
* Create a WorkManager.
*/
public GeronimoWorkManager() {
}
/**
* Provides the GeronimoMBean description for this class
* @return
*/
public static GeronimoMBeanInfo getGeronimoMBeanInfo() throws Exception {
// TODO: add descriptions to all operations.
GeronimoMBeanInfo rc = new GeronimoMBeanInfo();
rc.setTargetClass(GeronimoWorkManager.class);
rc.addOperationInfo(
new GeronimoOperationInfo(
"setSyncExecutor",
new GeronimoParameterInfo[] { new GeronimoParameterInfo("pool", WorkExecutorPool.class, "")},
MBeanOperationInfo.ACTION,
""));
rc.addOperationInfo(
new GeronimoOperationInfo(
"setStartExecutor",
new GeronimoParameterInfo[] { new GeronimoParameterInfo("pool", WorkExecutorPool.class, "")},
MBeanOperationInfo.ACTION,
""));
rc.addOperationInfo(
new GeronimoOperationInfo(
"setAsyncExecutor",
new GeronimoParameterInfo[] { new GeronimoParameterInfo("pool", WorkExecutorPool.class, "")},
MBeanOperationInfo.ACTION,
""));
return rc;
}
/**
* Set the executor in charge of the processing of synchronous works.
* @param anExecutorPool An executor.
*/
public void setSyncExecutor(WorkExecutorPool anExecutorPool) {
m_syncWorkExecutorPool = anExecutorPool;
}
/**
* Set the executor in charge of the processing of synchronous until start
* works.
* @param anExecutorPool An executor.
*/
public void setStartExecutor(WorkExecutorPool anExecutorPool) {
m_startWorkExecutorPool = anExecutorPool;
}
/**
* Set the executor in charge of the processing of asynchronous works.
* @param anExecutorPool An executor.
*/
public void setAsyncExecutor(WorkExecutorPool anExecutorPool) {
m_scheduledWorkExecutorPool = anExecutorPool;
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#doWork(javax.resource.spi.work.Work)
*/
public void doWork(Work work) throws WorkException {
checkStateBeforeAccept(m_syncWorkExecutorPool, "synchronous");
m_syncWorkExecutorPool.executeWork(new WorkerContext(work));
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#doWork(javax.resource.spi.work.Work, long, javax.resource.spi.work.ExecutionContext, javax.resource.spi.work.WorkListener)
*/
public void doWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) throws WorkException {
checkStateBeforeAccept(m_syncWorkExecutorPool, "synchronous");
WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
workWrapper.setThreadPriority(Thread.currentThread().getPriority());
m_syncWorkExecutorPool.executeWork(workWrapper);
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#startWork(javax.resource.spi.work.Work)
*/
public long startWork(Work work) throws WorkException {
checkStateBeforeAccept(m_startWorkExecutorPool, "synchronous until start");
WorkerContext workWrapper = new WorkerContext(work);
workWrapper.setThreadPriority(Thread.currentThread().getPriority());
m_startWorkExecutorPool.executeWork(workWrapper);
return System.currentTimeMillis() - workWrapper.getAcceptedTime();
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#startWork(javax.resource.spi.work.Work, long, javax.resource.spi.work.ExecutionContext, javax.resource.spi.work.WorkListener)
*/
public long startWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) throws WorkException {
checkStateBeforeAccept(m_startWorkExecutorPool, "synchronous until start");
WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
workWrapper.setThreadPriority(Thread.currentThread().getPriority());
m_startWorkExecutorPool.executeWork(workWrapper);
return System.currentTimeMillis() - workWrapper.getAcceptedTime();
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#scheduleWork(javax.resource.spi.work.Work)
*/
public void scheduleWork(Work work) throws WorkException {
checkStateBeforeAccept(m_scheduledWorkExecutorPool, "asynchronous");
WorkerContext workWrapper = new WorkerContext(work);
workWrapper.setThreadPriority(Thread.currentThread().getPriority());
m_scheduledWorkExecutorPool.executeWork(workWrapper);
}
/* (non-Javadoc)
* @see javax.resource.spi.work.WorkManager#scheduleWork(javax.resource.spi.work.Work, long, javax.resource.spi.work.ExecutionContext, javax.resource.spi.work.WorkListener)
*/
public void scheduleWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) throws WorkException {
checkStateBeforeAccept(m_scheduledWorkExecutorPool, "asynchronous");
WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
workWrapper.setThreadPriority(Thread.currentThread().getPriority());
m_scheduledWorkExecutorPool.executeWork(workWrapper);
}
/**
* This method MUST be called prior to accept a Work instance. It ensures
* that the state of this WorkManager is running.
*
* @throws WorkRejectedException Indicates that this WorkManager is not
* running and hence that a work can not be accepted.
*/
private void checkStateBeforeAccept(WorkExecutorPool aPool, String aType) throws WorkRejectedException {
try {
if (!(geronimoMBeanContext.getState() == State.RUNNING_INDEX)) {
throw new WorkRejectedException("WorkManager is not running.", WorkException.INTERNAL);
} else if (null == aPool) {
throw new WorkRejectedException(
"WorkManager is not partially" + " running. Its " + aType + " work facilities are unmounted.",
WorkException.INTERNAL);
}
} catch (Exception e) {
throw new WorkRejectedException("WorkManager is not ready.", WorkException.INTERNAL);
}
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#setMBeanContext(org.apache.geronimo.kernel.service.GeronimoMBeanContext)
*/
public void setMBeanContext(GeronimoMBeanContext geronimoMBeanContext) {
this.geronimoMBeanContext = geronimoMBeanContext;
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#canStart()
*/
public boolean canStart() {
return true;
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#doStart()
*/
public void doStart() {
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#canStop()
*/
public boolean canStop() {
return true;
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#doStop()
*/
public void doStop() {
}
/**
* @see org.apache.geronimo.kernel.service.GeronimoMBeanTarget#doFail()
*/
public void doFail() {
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/WorkManagerUtil.java
Index: WorkManagerUtil.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.geronimo.kernel.jmx.JMXUtil;
import org.apache.geronimo.kernel.jmx.MBeanProxyFactory;
/**
* WorkManager helper.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class WorkManagerUtil
{
/**
* Name of the WorkManager.
*/
public static final ObjectName WORK_MANAGER_NAME =
JMXUtil.getObjectName("geronimo.jca:role=WorkManager");
/**
* Name of the synchronous work executor.
*/
public static final ObjectName SYNC_EXECUTOR_NAME =
JMXUtil.getObjectName("geronimo.jca:role=SynchWorkExecutorPool");
/**
* Name of the synchronous until start work executor.
*/
public static final ObjectName START_EXECUTOR_NAME =
JMXUtil.getObjectName("geronimo.jca:role=StartWorkExecutorPool");
/**
* Name of the asynchronous work executor.
*/
public static final ObjectName ASYNC_EXECUTOR_NAME =
JMXUtil.getObjectName("geronimo.jca:role=ScheduleWorkExecutorPool");
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/WorkerContext.java
Index: WorkerContext.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work;
import javax.resource.spi.work.ExecutionContext;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkAdapter;
import javax.resource.spi.work.WorkCompletedException;
import javax.resource.spi.work.WorkEvent;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkListener;
import javax.resource.spi.work.WorkRejectedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import EDU.oswego.cs.dl.util.concurrent.Latch;
/**
* Work wrapper providing an execution context to a Work instance.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class WorkerContext implements Work
{
private Log m_log = LogFactory.getLog(WorkerContext.class);
/**
* Null WorkListener used as the default WorkListener.
*/
private static final WorkListener NULL_WORK_LISTENER = new WorkAdapter();
/**
* Priority of the thread which will execute this work.
*/
private int m_threadPriority;
/**
* Actual work to be executed.
*/
private Work m_adaptee;
/**
* Indicates if this work has been accepted.
*/
private boolean m_isAccepted;
/**
* System.currentTimeMillis() when the Work has been accepted.
*/
private long m_acceptedTime;
/**
* Number of times that the execution of this work has been tried.
*/
private int m_nbRetry;
/**
* time duration (in milliseconds) within which the execution of the Work
* instance must start.
*/
private long m_startTimeOut;
/**
* execution context of the actual work to be executed.
*/
private ExecutionContext m_executionContext;
/**
* Listener to be notified during the life-cycle of the work treatment.
*/
private WorkListener m_workListener = NULL_WORK_LISTENER;
/**
* Work exception if any.
*/
private WorkException m_workException;
/**
* A latch which is released when the work is started.
*/
private Latch m_startLatch = new Latch();
/**
* A latch which is released when the work is completed.
*/
private Latch m_endLatch = new Latch();
/**
* Create a WorkWrapper.
*
* @param aWork Work wrapped by this instance.
*/
public WorkerContext(Work aWork) {
m_adaptee = aWork;
}
/**
* Create a WorkWrapper with the specified execution context.
*
* @param aWork Work wrapped by this instance.
* @param aStartTimeout a time duration (in milliseconds) within which the
* execution of the Work instance must start.
* @param execContext an object containing the execution context with which
* the submitted Work instance must be executed.
* @param workListener an object which would be notified when the various
* Work processing events (work accepted, work rejected, work started,
* work completed) occur.
*/
public WorkerContext(Work aWork, long aStartTimeout,
ExecutionContext execContext,
WorkListener workListener) {
m_adaptee = aWork;
m_startTimeOut = aStartTimeout;
m_executionContext = execContext;
if ( null != workListener ) {
m_workListener = workListener;
}
}
/* (non-Javadoc)
* @see javax.resource.spi.work.Work#release()
*/
public void release() {
m_adaptee.release();
}
/**
* Defines the thread priority level of the thread which will be dispatched
* to process this work. This priority level must be the same one for a
* given resource adapter.
*/
public void setThreadPriority(int aPriority) {
m_threadPriority = aPriority;
}
/**
* Gets the thread priority level of the thread which will be dispatched
* to process this work. This priority level must be the same one for a
* given resource adapter.
*/
public int getThreadPriority() {
return m_threadPriority;
}
/**
* Used by a Work executor in order to notify this work that it has been
* accepted.
*
* @param anObject Object on which the event initially occurred. It should
* be the work executor.
*/
public synchronized void workAccepted(Object anObject) {
m_isAccepted = true;
m_acceptedTime = System.currentTimeMillis();
m_workListener.workAccepted(new WorkEvent(anObject,
WorkEvent.WORK_ACCEPTED, m_adaptee, null));
}
/**
* System.currentTimeMillis() when the Work has been accepted.
*
* @return when the work has ben accepted.
*/
public synchronized long getAcceptedTime() {
return m_acceptedTime;
}
/**
* Gets the time duration (in milliseconds) within which the execution of
* the Work instance must start.
*
* @return time out duration.
*/
public long getStartTimeout() {
return m_startTimeOut;
}
/**
* Used by a Work executor in order to know if this work, which should be
* accepted but not started has timed out. This method MUST be called prior
* to retry the execution of a Work.
*
* @return true if the work has timed out and false otherwise.
*/
public synchronized boolean isTimedOut() {
assert !m_isAccepted: "The work is not accepted.";
// A value of 0 means that the work never times out.
if ( 0 == m_startTimeOut ) {
return false;
}
boolean isTimeout =
System.currentTimeMillis() > m_acceptedTime + m_startTimeOut;
if ( m_log.isDebugEnabled() ) {
m_log.debug(this + " accepted at " + m_acceptedTime +
(isTimeout? " has timed out.":" has not timed out. ") +
m_nbRetry + " retries have been performed.");
}
if ( isTimeout ) {
m_workException = new WorkRejectedException("Time out.",
WorkException.START_TIMED_OUT);
m_workListener.workRejected(
new WorkEvent(this, WorkEvent.WORK_REJECTED, m_adaptee,
m_workException));
return true;
}
m_nbRetry++;
return isTimeout;
}
/**
* Gets the WorkException, if any, thrown during this work execution.
*
* @return WorkException, if any.
*/
public synchronized WorkException getWorkException() {
return m_workException;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
if ( isTimedOut() ) {
// In case of a time out, one releases the start and end latches
// to prevent a dead-lock.
m_startLatch.release();
m_endLatch.release();
return;
}
// Implementation note: the work listener is notified prior to release
// the start lock. This behavior is intentional and seems to be the
// more conservative.
m_workListener.workStarted(
new WorkEvent(this, WorkEvent.WORK_STARTED, m_adaptee, null));
m_startLatch.release();
try {
m_adaptee.run();
m_workListener.workCompleted(
new WorkEvent(this, WorkEvent.WORK_COMPLETED, m_adaptee, null));
} catch (Throwable e) {
m_workException = new WorkCompletedException(e);
m_workListener.workRejected(
new WorkEvent(this, WorkEvent.WORK_REJECTED, m_adaptee,
m_workException));
} finally {
m_endLatch.release();
}
}
/**
* Provides a latch, which can be used to wait the start of a work
* execution.
*
* @return Latch that a caller can acquire to wait for the start of a
* work execution.
*/
public synchronized Latch provideStartLatch() {
return m_startLatch;
}
/**
* Provides a latch, which can be used to wait the end of a work
* execution.
*
* @return Latch that a caller can acquire to wait for the end of a
* work execution.
*/
public synchronized Latch provideEndLatch() {
return m_endLatch;
}
public String toString() {
return "Work :" + m_adaptee;
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/AbstractWorkExecutorPool.java
Index: AbstractWorkExecutorPool.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import javax.resource.spi.work.WorkCompletedException;
import javax.resource.spi.work.WorkException;
import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.connector.work.WorkerContext;
import EDU.oswego.cs.dl.util.concurrent.Channel;
/**
* Based class for WorkExecutorPool. A sub-class defines the synchronization
* policy (should the call block until the end of the work; or when it starts
* et cetera).
*
* @jmx:mbean
* extends="org.apache.geronimo.kernel.management.StateManageable,org.apache.geronimo.kernel.management.ManagedObject"
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public abstract class AbstractWorkExecutorPool implements WorkExecutorPool {
/**
* A timed out pooled executor.
*/
private TimedOutPooledExecutor m_pooledExecutor;
/**
* Creates a pool with the specified minimum and maximum sizes.
*
* @param aMinSize Minimum size of the work executor pool.
* @param aMaxSize Maximum size of the work executor pool.
* @param aRetryDuration Duration (in milliseconds) to wait prior to retry
* the execution of a Work.
*/
public AbstractWorkExecutorPool(int aMinSize, int aMaxSize) {
m_pooledExecutor = new TimedOutPooledExecutor();
m_pooledExecutor.setMinimumPoolSize(aMinSize);
m_pooledExecutor.setMaximumPoolSize(aMaxSize);
m_pooledExecutor.waitWhenBlocked();
}
/**
* Creates a pool with the specified minimum and maximum sizes.
*
* @param Queue to be used on top of the pool.
* @param aMinSize Minimum size of the work executor pool.
* @param aMaxSize Maximum size of the work executor pool.
* @param aRetryDuration Duration (in milliseconds) to wait prior to retry
* the execution of a Work.
*/
public AbstractWorkExecutorPool(Channel aChannel, int aMinSize, int aMaxSize) {
m_pooledExecutor = new TimedOutPooledExecutor(aChannel);
m_pooledExecutor.setMinimumPoolSize(aMinSize);
m_pooledExecutor.setMaximumPoolSize(aMaxSize);
m_pooledExecutor.waitWhenBlocked();
}
/**
* Delegates the work execution to the pooled executor.
*
* @see EDU.oswego.cs.dl.util.concurrent.PooledExecutor#execute(java.lang.Runnable)
*/
protected void execute(WorkerContext aWork) throws InterruptedException {
m_pooledExecutor.execute(aWork);
}
/**
* @see org.apache.geronimo.workmanagement.WorkExecutorPool#execute(org.apache.geronimo.workmanagement.WorkWrapper)
*/
public void executeWork(WorkerContext aWork) throws WorkException {
aWork.workAccepted(this);
try {
doExecute(aWork);
WorkException exception = aWork.getWorkException();
if (null != exception) {
throw exception;
}
} catch (InterruptedException e) {
WorkCompletedException wcj = new WorkCompletedException("The execution has been interrupted.", e);
wcj.setErrorCode(WorkException.INTERNAL);
throw wcj;
}
}
public static GeronimoMBeanInfo getGeronimoMBeanInfo() throws Exception {
GeronimoMBeanInfo rc = new GeronimoMBeanInfo();
rc.setTargetClass(AbstractWorkExecutorPool.class);
rc.addAttributeInfo(new GeronimoAttributeInfo("PoolSize", true, false));
rc.addAttributeInfo(new GeronimoAttributeInfo("MinimumPoolSize", true, true));
rc.addAttributeInfo(new GeronimoAttributeInfo("MaximumPoolSize", true, true));
return rc;
}
/**
* @see org.apache.geronimo.work.WorkExecutorPool#getPoolSize()
*/
public int getPoolSize() {
return m_pooledExecutor.getPoolSize();
}
/**
* @see org.apache.geronimo.work.WorkExecutorPool#getMinimumPoolSize()
*/
public int getMinimumPoolSize() {
return m_pooledExecutor.getMinimumPoolSize();
}
/**
* @see org.apache.geronimo.work.WorkExecutorPool#setMinimumPoolSize(int)
*/
public void setMinimumPoolSize(int aSize) {
m_pooledExecutor.setMinimumPoolSize(aSize);
}
/**
* @see org.apache.geronimo.work.WorkExecutorPool#getMaximumPoolSize()
*/
public int getMaximumPoolSize() {
return m_pooledExecutor.getMaximumPoolSize();
}
/**
* @see org.apache.geronimo.work.WorkExecutorPool#setMaximumPoolSize(int)
*/
public void setMaximumPoolSize(int aSize) {
m_pooledExecutor.setMaximumPoolSize(aSize);
}
/**
* This method must be implemented by sub-classes in order to provide a
* synchronization policy.
*
* @param aWork Work to be executed.
*
* @throws WorkException Indicates the work has failed.
* @throws InterruptedException Indicates that the thread in charge of the
* execution of the specified work dies.
*/
protected abstract void doExecute(WorkerContext aWork) throws WorkException, InterruptedException;
/* (non-Javadoc)
* @see org.apache.geronimo.connector.WorkExecutorPool#stop()
*/
public void doStop() {
m_pooledExecutor.shutdownAfterProcessingCurrentlyQueuedTasks();
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/ScheduleWorkExecutorPool.java
Index: ScheduleWorkExecutorPool.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.resource.spi.work.WorkException;
import org.apache.geronimo.kernel.service.GeronimoMBeanEndpoint;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.connector.work.GeronimoWorkManager;
import org.apache.geronimo.connector.work.WorkerContext;
import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
/**
* WorkExecutorPool which treats the submitted Work instances asynchronously.
* More accurately, its execute method returns immediately after the work
* submission.
*
* @jmx:mbean extends="AbstractWorkExecutorPoolMBean"
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class ScheduleWorkExecutorPool
extends AbstractWorkExecutorPool
{
/**
* Creates a pool with the specified minimum and maximum sizes.
*
* @param aMinSize Minimum size of the work executor pool.
* @param aMaxSize Maximum size of the work executor pool.
*/
public ScheduleWorkExecutorPool(int aMinSize, int aMaxSize) {
super(new LinkedQueue(), aMinSize, aMaxSize);
}
public void setGeronimoWorkManager( GeronimoWorkManager wm ) {
wm.setAsyncExecutor(this);
}
/**
*/
public void doExecute(WorkerContext aWork)
throws WorkException, InterruptedException {
super.execute(aWork);
}
public static GeronimoMBeanInfo getGeronimoMBeanInfo() throws Exception {
try {
GeronimoMBeanInfo rc =AbstractWorkExecutorPool.getGeronimoMBeanInfo();
rc.setTargetClass(ScheduleWorkExecutorPool.class);
rc.addEndpoint(new GeronimoMBeanEndpoint("GeronimoWorkManager", GeronimoWorkManager.class, new ObjectName("geronimo.jca:role=WorkManager"), true));
return rc;
} catch (MalformedObjectNameException e) {
throw new RuntimeException("GeronimoMBeanInfo could not be gernerated.", e);
}
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/StartWorkExecutorPool.java
Index: StartWorkExecutorPool.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.resource.spi.work.WorkException;
import org.apache.geronimo.kernel.service.GeronimoMBeanEndpoint;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.connector.work.GeronimoWorkManager;
import org.apache.geronimo.connector.work.WorkerContext;
import EDU.oswego.cs.dl.util.concurrent.Latch;
import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
/**
* WorkExecutorPool which treats the submitted Work instances synchronously
* until the work starts. More accurately, its execute method returns when the
* work is started.
*
* @jmx:mbean extends="AbstractWorkExecutorPoolMBean"
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class StartWorkExecutorPool
extends AbstractWorkExecutorPool
{
/**
* Creates a pool with the specified minimum and maximum sizes.
*
* @param aMinSize Minimum size of the work executor pool.
* @param aMaxSize Maximum size of the work executor pool.
*/
public StartWorkExecutorPool(int aMinSize, int aMaxSize) {
super(new LinkedQueue(), aMinSize, aMaxSize);
}
public void setGeronimoWorkManager( GeronimoWorkManager wm ) {
wm.setStartExecutor(this);
}
/**
* In the case of a synchronous execution, the Work has been executed and
* one needs to retrieve the WorkException thrown during this execution, if
* any.
*
* @exception WorkException Not thrown.
* @exception InterruptedException Indicates that this work execution
* has been interrupted.
*/
public void doExecute(WorkerContext aWork)
throws WorkException, InterruptedException {
Latch latch = aWork.provideStartLatch();
super.execute(aWork);
latch.acquire();
}
public static GeronimoMBeanInfo getGeronimoMBeanInfo() throws Exception {
try {
GeronimoMBeanInfo rc =AbstractWorkExecutorPool.getGeronimoMBeanInfo();
rc.setTargetClass(StartWorkExecutorPool.class);
rc.addEndpoint(new GeronimoMBeanEndpoint("GeronimoWorkManager", GeronimoWorkManager.class, new ObjectName("geronimo.jca:role=WorkManager"), true));
return rc;
} catch (MalformedObjectNameException e) {
throw new RuntimeException("GeronimoMBeanInfo could not be gernerated.", e);
}
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/SyncWorkExecutorPool.java
Index: SyncWorkExecutorPool.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.resource.spi.work.WorkException;
import org.apache.geronimo.kernel.service.GeronimoMBeanEndpoint;
import org.apache.geronimo.kernel.service.GeronimoMBeanInfo;
import org.apache.geronimo.connector.work.GeronimoWorkManager;
import org.apache.geronimo.connector.work.WorkerContext;
import EDU.oswego.cs.dl.util.concurrent.Latch;
/**
* WorkExecutorPool which treats the submitted Work instances synchronously.
* More accurately, its execute method blocks until the work is completed.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class SyncWorkExecutorPool
extends AbstractWorkExecutorPool
{
/**
* Creates a pool with the specified minimum and maximum sizes.
*
* @param aMinSize Minimum size of the work executor pool.
* @param aMaxSize Maximum size of the work executor pool.
*/
public SyncWorkExecutorPool(int aMinSize, int aMaxSize) {
super(aMinSize, aMaxSize);
}
public void setGeronimoWorkManager( GeronimoWorkManager wm ) {
wm.setSyncExecutor(this);
}
/**
* In the case of a synchronous execution, the Work has been executed and
* one needs to retrieve the WorkException thrown during this execution, if
* any.
*
* @exception WorkException Not thrown.
* @exception InterruptedException Indicates that this work execution
* has been interrupted.
*/
public void doExecute(WorkerContext aWork)
throws WorkException, InterruptedException {
Latch latch = aWork.provideEndLatch();
super.execute(aWork);
latch.acquire();
}
public static GeronimoMBeanInfo getGeronimoMBeanInfo() throws Exception {
try {
GeronimoMBeanInfo rc =AbstractWorkExecutorPool.getGeronimoMBeanInfo();
rc.setTargetClass(SyncWorkExecutorPool.class);
rc.addEndpoint(new GeronimoMBeanEndpoint("GeronimoWorkManager", GeronimoWorkManager.class, new ObjectName("geronimo.jca:role=WorkManager"), true));
return rc;
} catch (MalformedObjectNameException e) {
throw new RuntimeException("GeronimoMBeanInfo could not be gernerated.", e);
}
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/TimedOutPooledExecutor.java
Index: TimedOutPooledExecutor.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import org.apache.geronimo.connector.work.WorkerContext;
import EDU.oswego.cs.dl.util.concurrent.Channel;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
/**
* PooledExecutor enforcing a timed out "blocked execution policy". The works
* submitted to this pooled executor MUST be a WorkWrapper.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class TimedOutPooledExecutor extends PooledExecutor
{
public TimedOutPooledExecutor() {
setBlockedExecutionHandler(new TimedOutSpinHandler());
}
public TimedOutPooledExecutor(Channel aChannel) {
super(aChannel);
setBlockedExecutionHandler(new TimedOutSpinHandler());
}
/**
* Executes the provided task, which MUST be an instance of WorkWrapper.
*
* @throws IllegalArgumentException Indicates that the provided task is not
* a WorkWrapper.
*/
public void execute(Runnable aTask) throws InterruptedException {
if ( aTask instanceof WorkerContext ) {
super.execute(aTask);
return;
}
throw new IllegalArgumentException("Please submit a WorkWrapper");
}
/**
* This class implements a time out policy when a work is blocked: it offers
* the task to the pool until the work has timed out.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
private class TimedOutSpinHandler
implements PooledExecutor.BlockedExecutionHandler {
/* (non-Javadoc)
* @see EDU.oswego.cs.dl.util.concurrent.PooledExecutor.BlockedExecutionHandler#blockedAction(java.lang.Runnable)
*/
public boolean blockedAction(Runnable arg0) throws InterruptedException {
WorkerContext work = (WorkerContext) arg0;
if ( !handOff_.offer(arg0, work.getStartTimeout()) ) {
// double check.
if ( work.isTimedOut() ) {
return false;
}
return true;
}
return true;
}
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/connector/work/pool/WorkExecutorPool.java
Index: WorkExecutorPool.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work.pool;
import javax.resource.spi.work.WorkException;
import org.apache.geronimo.connector.work.WorkerContext;
/**
* Defines the operations that a pool in charge of the execution of Work
* instances must expose.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public interface WorkExecutorPool
{
/**
* Executes the specified work. The execution policy (synchronous vs.
* asynchronous) is implementation specific.
*
* @param aWork Work to be executed.
*
* @throws WorkException Indicates that the Work instance can not be
* executed or that its execution has thrown an exception.
*/
public void executeWork(WorkerContext aWork) throws WorkException;
/**
* Gets the current number of active threads in the pool.
*
* @return Number of active threads in the pool.
*/
public int getPoolSize();
/**
* Gets the minimum number of threads to simultaneously execute.
*
* @return Minimum size.
*/
public int getMinimumPoolSize();
/**
* Sets the minimum number of threads to simultaneously execute.
*
* @param aSize Minimum size.
*/
public void setMinimumPoolSize(int aSize);
/**
* Gets the maximum number of threads to simultaneously execute.
*
* @return Maximim size.
*/
public int getMaximumPoolSize();
/**
* Sets the maximum number of threads to simultaneously execute.
*
* @param Maximum size.
*/
public void setMaximumPoolSize(int aSize);
}
1.1 incubator-geronimo/modules/core/src/test/org/apache/geronimo/connector/work/PooledWorkManagerTest.java
Index: PooledWorkManagerTest.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.connector.work;
import java.lang.reflect.Constructor;
import javax.resource.spi.work.ExecutionContext;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkEvent;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkListener;
import javax.resource.spi.work.WorkManager;
import junit.framework.TestCase;
import org.apache.geronimo.kernel.jmx.JMXKernel;
import org.apache.geronimo.kernel.management.State;
import org.apache.geronimo.kernel.service.GeronimoMBeanContext;
import org.apache.geronimo.connector.work.pool.ScheduleWorkExecutorPool;
import org.apache.geronimo.connector.work.pool.StartWorkExecutorPool;
import org.apache.geronimo.connector.work.pool.SyncWorkExecutorPool;
/**
* Timing is crucial for this test case, which focuses on the synchronous
* specificities of the doWork, startWork and scheduleWork.
*
* @version $Revision: 1.1 $ $Date: 2003/11/16 22:42:20 $
*/
public class PooledWorkManagerTest extends TestCase
{
private JMXKernel m_kernel;
private GeronimoWorkManager m_workManager;
private static final int m_nbMin = 1;
private static final int m_nbMax = 1;
private static final int m_timeout = 3000;
private static final int m_tempo = 2000;
public PooledWorkManagerTest() throws Exception {
super("WorkManager");
initMinimalisticServer();
m_workManager = new GeronimoWorkManager();
// We are mocking the GeronimoMBeanContext
m_workManager.setMBeanContext(new GeronimoMBeanContext(null, null, null){
public int getState() throws Exception {
return State.RUNNING_INDEX;
}
});
SyncWorkExecutorPool syncWorkExecutorPool = new SyncWorkExecutorPool(1, 1);
syncWorkExecutorPool.setGeronimoWorkManager(m_workManager);
StartWorkExecutorPool startWorkExecutorPool = new StartWorkExecutorPool(1, 1);
startWorkExecutorPool.setGeronimoWorkManager(m_workManager);
ScheduleWorkExecutorPool scheduleWorkExecutorPool = new ScheduleWorkExecutorPool(1, 1);
scheduleWorkExecutorPool.setGeronimoWorkManager(m_workManager);
}
public void initMinimalisticServer() throws Exception {
}
public void testDoWork() throws Exception {
int nbThreads = 3;
AbstractDummyWork threads[] = helperTest(DummyDoWork.class, nbThreads);
int nbStopped = 0;
int nbTimeout = 0;
for (int i = 0; i < threads.length; i++) {
if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_COMPLETED ) {
nbStopped++;
} else if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_REJECTED ) {
assertTrue("Should be a time out exception.",
threads[i].m_listener.m_event.getException().
getErrorCode() == WorkException.START_TIMED_OUT);
nbTimeout++;
} else {
assertTrue("Works should be either in the WORK_COMPLETED or " +
"WORK_REJECTED state", false);
}
}
assertTrue("Wrong number of works in the WORK_COMPLETED state: " +
"expected " + (nbThreads - 1 ) + "; retrieved " + nbStopped,
(nbThreads - 1 ) == nbStopped);
assertTrue("Wrong number of works in the START_TIMED_OUT state: " +
"expected 1; retrieved " + nbTimeout, 1 == nbTimeout);
}
public void testStartWork() throws Exception {
AbstractDummyWork threads[] = helperTest(DummyStartWork.class, 2);
int nbStopped = 0;
int nbStarted = 0;
for (int i = 0; i < threads.length; i++) {
if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_COMPLETED ) {
nbStopped++;
} else if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_STARTED ) {
nbStarted++;
} else {
assertTrue("Works should be either in the WORK_COMPLETED or " +
"WORK_STARTED state", false);
}
}
assertTrue("At least one work should be in the WORK_COMPLETED state.",
nbStopped == 1);
assertTrue("At least one work should be in the WORK_STARTED state.",
nbStarted == 1);
}
public void testScheduleWork() throws Exception {
AbstractDummyWork threads[] = helperTest(DummyScheduleWork.class, 3);
int nbAccepted = 0;
int nbStarted = 0;
for (int i = 0; i < threads.length; i++) {
if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_ACCEPTED ) {
nbAccepted++;
} else if ( threads[i].m_listener.m_event.getType() ==
WorkEvent.WORK_STARTED ) {
nbStarted++;
} else {
assertTrue("Works should be eithe in the WORK_ACCEPTED or" +
" WORK_STARTED state.", false);
}
}
assertTrue("At least one work should be in the WORK_ACCEPTED state.",
nbAccepted > 0);
}
private AbstractDummyWork[] helperTest(Class aWork, int nbThreads)
throws Exception {
Constructor constructor = aWork.getConstructor(
new Class[]{WorkManager.class, String.class});
AbstractDummyWork rarThreads[] =
new AbstractDummyWork[nbThreads];
for (int i = 0; i < nbThreads; i++) {
rarThreads[i] = (AbstractDummyWork) constructor.newInstance(
new Object[] {m_workManager, "Work" + i});
rarThreads[i].start();
}
for (int i = 0; i < nbThreads; i++) {
rarThreads[i].join();
}
return rarThreads;
}
private static abstract class AbstractDummyWork extends Thread {
public DummyWorkListener m_listener;
protected WorkManager m_workManager;
protected String m_name;
public AbstractDummyWork(WorkManager aWorkManager, String aName) {
m_workManager = aWorkManager;
m_listener = new DummyWorkListener();
m_name = aName;
}
public void run() {
try {
perform(new DummyWork(m_name), m_timeout, null, m_listener);
} catch (Exception e) {
e.printStackTrace();
}
}
protected abstract void perform(Work work,
long startTimeout,
ExecutionContext execContext,
WorkListener workListener) throws Exception;
}
private static class DummyDoWork extends AbstractDummyWork {
public DummyDoWork(WorkManager aWorkManager, String aName) {
super(aWorkManager, aName);
}
protected void perform(Work work,
long startTimeout,
ExecutionContext execContext,
WorkListener workListener) throws Exception {
m_workManager.doWork(work, startTimeout, execContext, workListener);
}
}
private static class DummyStartWork extends AbstractDummyWork {
public DummyStartWork(WorkManager aWorkManager, String aName) {
super(aWorkManager, aName);
}
protected void perform(Work work,
long startTimeout,
ExecutionContext execContext,
WorkListener workListener) throws Exception {
m_workManager.startWork(work, startTimeout, execContext, workListener);
}
}
private static class DummyScheduleWork extends AbstractDummyWork {
public DummyScheduleWork(WorkManager aWorkManager, String aName) {
super(aWorkManager, aName);
}
protected void perform(Work work,
long startTimeout,
ExecutionContext execContext,
WorkListener workListener) throws Exception {
m_workManager.scheduleWork(work, startTimeout, execContext, workListener);
}
}
private static class DummyWork implements Work {
private String m_name;
public DummyWork(String aName) {m_name = aName;}
public void release() {}
public void run() {
try {
Thread.sleep(m_tempo);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String toString() {return m_name;}
}
private static class DummyWorkListener implements WorkListener {
public WorkEvent m_event;
public void workAccepted(WorkEvent e) {m_event = e;}
public void workRejected(WorkEvent e) {m_event = e;}
public void workStarted(WorkEvent e) {m_event = e;}
public void workCompleted(WorkEvent e) {m_event = e;}
}
}