package org.radargun.service; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; import org.infinispan.Cache; import org.infinispan.distexec.DefaultExecutorService; import org.infinispan.distexec.DistributedExecutorService; import org.infinispan.distexec.DistributedTask; import org.infinispan.distexec.DistributedTaskBuilder; import org.infinispan.distexec.DistributedTaskExecutionPolicy; import org.infinispan.distexec.DistributedTaskFailoverPolicy; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.remoting.transport.Address; import org.infinispan.remoting.transport.Transport; import org.radargun.config.Destroy; import org.radargun.logging.Log; import org.radargun.logging.LogFactory; import org.radargun.traits.DistributedTaskExecutor; import org.radargun.utils.Utils; /** * A CacheWrapper that implements the DistributedTaskCapable interface, so it is capable of * executing a Callable against the cache using the DistributedExecutorService. * * @author Alan Field <afield@redhat.com> */ public class InfinispanDistributedTask<K, V, T> implements DistributedTaskExecutor<T> { protected final Log log = LogFactory.getLog(getClass()); protected final Infinispan52EmbeddedService service; protected final ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() { AtomicInteger counter = new AtomicInteger(); @Override public Thread newThread(Runnable r) { return new Thread(r, "DistributedTask-" + counter.incrementAndGet()); } }); public InfinispanDistributedTask(Infinispan52EmbeddedService service) { this.service = service; } @Destroy public void destroy() { Utils.shutdownAndWait(executorService); } protected class Builder implements DistributedTaskExecutor.Builder<T> { protected final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); protected final DistributedExecutorService executorService; protected Callable<T> callable; protected DistributedTaskExecutionPolicy executionPolicy; protected DistributedTaskFailoverPolicy failoverPolicy; protected Address target; public Builder(Cache<K, V> cache) { executorService = new DefaultExecutorService(cache, InfinispanDistributedTask.this.executorService); } @Override public DistributedTaskExecutor.Builder callable(Callable<T> callable) { this.callable = callable; return this; } @Override public DistributedTaskExecutor.Builder executionPolicy(String executionPolicy) { this.executionPolicy = DistributedTaskExecutionPolicy.valueOf(executionPolicy); return this; } @Override public DistributedTaskExecutor.Builder failoverPolicy(String failoverPolicy) { this.failoverPolicy = Utils.instantiate(failoverPolicy); return this; } @Override public DistributedTaskExecutor.Builder nodeAddress(String nodeAddress) { this.target = findHostPhysicalAddress(nodeAddress); return this; } @Override public Task build() { DistributedTaskBuilder<T> taskBuilder = executorService.createDistributedTaskBuilder(callable); if (executionPolicy != null) taskBuilder.executionPolicy(executionPolicy); if (failoverPolicy != null) taskBuilder.failoverPolicy(failoverPolicy); return new Task(executorService, taskBuilder.build(), target); } } protected class Task implements DistributedTaskExecutor.Task<T> { protected final DistributedExecutorService executorService; protected final DistributedTask<T> task; protected final Address target; public Task(DistributedExecutorService executorService, DistributedTask<T> task, Address target) { this.executorService = executorService; this.task = task; this.target = target; } @Override public List<Future<T>> execute() { if (target != null) { return Collections.singletonList((Future<T>) executorService.submit(target, task)); } else { return executorService.submitEverywhere(task); } } } @Override public Builder builder(String cacheName) { return new Builder((Cache<K, V>) service.getCache(cacheName)); } private Address findHostPhysicalAddress(String nodeAddress) { Transport t = ((DefaultCacheManager) service.cacheManager).getTransport(); if (t != null) { for (Address address : t.getPhysicalAddresses()) { if (address.toString().contains(nodeAddress)) { return address; } } } throw new IllegalArgumentException("Cannot find node with address " + nodeAddress); } }