čtvrtek 17. června 2010

WorkManager on WLS 10.3 with Spring 3.0

Yesterday I played with asynchronous job processing on WebLogic server 10.3. It is quite easy to use solution with is directly supported by Oracle(BEA) - commonj.
Also the integration to the spring 3.0 was straightforward.

At first, define the workmanager inside weblogic-application.xml

<work-manager>
<name>test_work_manager</name>

<min-threads-constraint>
<name>test-minimum-10</name>
<count>10</count>
</min-threads-constraint>

<max-threads-constraint>
<name>test-maximum-20</name>
<count>20</count>
</max-threads-constraint>
</work-manager>

Add resource reference to the web.xml.

<resource-ref>
<res-ref-name>test_work_manager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

Spring configuration is connected to the JDNI name.

<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="test_work_manager"/>
<property name="resourceRef" value="true"/>
</bean>

Example, how to run three jobs in parallel and stop current processing thread until all jobs are complete.

package com.blogspot.pcharvat.workmanager;

import commonj.work.Work;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

public class MyJob implements Work {

private final Logger log = LoggerFactory.getLogger(getClass());

private static final AtomicInteger COUNTER = new AtomicInteger();

@Override
public void run() {
log.debug("Running in ... " + COUNTER.incrementAndGet());
}

@Override
public void release() {

}

@Override
public boolean isDaemon() {
return false;
}
}


package com.blogspot.pcharvat.workmanager;

import commonj.work.WorkException;
import commonj.work.WorkItem;
import commonj.work.WorkManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import java.util.ArrayList;
import java.util.List;

public class AsyncCall {

private final Logger log = LoggerFactory.getLogger(getClass());

private WorkManager workManager;

public void runInParallel() {
try {
final MyJob jobA = new MyJob();
final MyJob jobB = new MyJob();
final MyJob jobC = new MyJob();

final List jobs = new ArrayList();
jobs.add(workManager.schedule(jobA));
jobs.add(workManager.schedule(jobB));
jobs.add(workManager.schedule(jobC));

final boolean result = workManager.waitForAll(jobs, 30000);// waits 30 seconds

log.debug("AsyncCall.runInParallel result={}", result);
} catch (WorkException e) {
log.error(e.getMessage(), e);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}

}

@Required
public void setWorkManager(final WorkManager workManager) {
this.workManager = workManager;
}
}