package com.breakersoft.plow.rndaemon; import java.util.concurrent.ExecutionException; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import com.breakersoft.plow.dispatcher.DispatchService; import com.breakersoft.plow.dispatcher.domain.DispatchProc; import com.breakersoft.plow.dispatcher.domain.DispatchTask; import com.breakersoft.plow.dispatcher.pipeline.AbortedTaskCommand; import com.breakersoft.plow.dispatcher.pipeline.PipelineController; import com.breakersoft.plow.exceptions.RndClientConnectionError; import com.breakersoft.plow.rnd.thrift.RunTaskCommand; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @Component public class RndClientPool { private static final Logger logger = org.slf4j.LoggerFactory.getLogger(RndClientPool.class); // Cache that maps a path to a group private final LoadingCache<String, RndClient> rndClientCache; @Autowired private DispatchService dispatchService; @Autowired private PipelineController pipelineController; @Autowired @Qualifier("rndCommandExecutor") private ThreadPoolTaskExecutor rndCommandExecutor; public RndClientPool() { rndClientCache = CacheBuilder.newBuilder() .initialCapacity(200) .concurrencyLevel(8) .build(new CacheLoader<String, RndClient>() { @Override public RndClient load(final String key) throws Exception { RndClient client = new RndClient(key); client.connect(); return client; } }); } public RndClient get(String hostname) { try { return rndClientCache.get(hostname); } catch (ExecutionException e) { throw new RndClientConnectionError("Rnd connection error: " + e, e); } } public void executeProcess(DispatchProc proc, DispatchTask task) { rndCommandExecutor.execute(new RunProcessCommand(proc, task)); } private class RunProcessCommand implements Runnable { private final DispatchProc proc; private final DispatchTask task; public RunProcessCommand(DispatchProc proc, DispatchTask task) { this.proc = proc; this.task = task; } @Override public void run() { final RunTaskCommand command = dispatchService.getRuntaskCommand(task); try { RndClient client = rndClientCache.get(proc.getHostname()); client.runProcess(command); return; } catch (ExecutionException e) { logger.error("Unable to obtain cached RND client connection: " + e); } catch (RuntimeException e) { logger.error("Failed to execute run process on host: " + proc.getHostname() + "," + e); } // Handle case where task is rejected from rndaemon. pipelineController.execute(new AbortedTaskCommand(proc, task, dispatchService)); } } }