org.apache.servicemix.beanflow.ParallelActivity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of servicemix-beanflow Show documentation
Show all versions of servicemix-beanflow Show documentation
A library for orchestrating beans and asynchronous events using
regular POJOs rather than XML
The newest version!
/*
* 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.apache.servicemix.beanflow;
import org.apache.servicemix.beanflow.support.CallablesFactory;
import org.apache.servicemix.beanflow.support.FindCallableMethods;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* An activity which invokes a collection of {@link Callable} methods.
*
* @version $Revision: $
*/
public class ParallelActivity extends ProxyActivity {
private JoinSupport joinActivity;
private List> activities;
private AtomicBoolean started = new AtomicBoolean();
private Object lock = new Object();
private CountDownLatch countDownLatch;
/**
* A helper method to create a new {@link ParallelActivity} which invokes a
* number of methods on a POJO in parallel and then joins on them all
* completing
*/
public static ParallelActivity newParallelMethodActivity(Executor executor, Object bean) {
return newParallelMethodActivity(new JoinAll(), executor, bean);
}
/**
* A helper method to create a new {@link ParallelActivity} which invokes a
* number of methods on a POJO in parallel and then performs a custom join
*/
@SuppressWarnings("unchecked")
public static ParallelActivity newParallelMethodActivity(JoinSupport join, Executor executor, Object bean) {
return new ParallelActivity(join, executor, new FindCallableMethods(bean));
}
public ParallelActivity(JoinSupport activity, Executor executor, CallablesFactory callablesFactory) {
this(activity, executor, callablesFactory.createCallables());
}
public ParallelActivity(JoinSupport activity, Executor executor, List> callables) {
super(activity);
this.joinActivity = activity;
this.activities = new ArrayList>();
for (Callable callable : callables) {
activities.add(new CallableActivity(executor, callable));
}
}
public ParallelActivity(JoinSupport activity, List> activities) {
super(activity);
this.joinActivity = activity;
this.activities = activities;
}
public List> getFutures() {
List> answer = new ArrayList>();
synchronized (lock) {
for (CallableActivity activity : activities) {
answer.add(activity.getFuture());
}
}
return answer;
}
@Override
public void start() {
super.start();
init();
}
@Override
public void startWithTimeout(Timer timer, long timeout) {
init();
super.startWithTimeout(timer, timeout);
}
public void sync() {
try {
CountDownLatch latch = getCountDownLatch();
latch.countDown();
latch.await();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
finally {
resetCountDownLatch();
}
}
public boolean sync(long millis) {
try {
CountDownLatch latch = getCountDownLatch();
latch.countDown();
return latch.await(millis, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
finally {
resetCountDownLatch();
}
}
// Implementation methods
// -------------------------------------------------------------------------
protected void resetCountDownLatch() {
synchronized (lock) {
if (countDownLatch != null && countDownLatch.getCount() == 0) {
countDownLatch = null;
}
}
}
protected CountDownLatch getCountDownLatch() {
synchronized (lock) {
int count = activities.size();
if (countDownLatch == null) {
countDownLatch = new CountDownLatch(count);
}
return countDownLatch;
}
}
private void init() {
if (started.compareAndSet(false, true)) {
doStart();
}
}
protected void doStart() {
for (CallableActivity activity : activities) {
joinActivity.fork(activity);
}
}
}