package codeine.command_peer;
import java.util.List;
import java.util.concurrent.ExecutorService;
import org.apache.log4j.Logger;
import codeine.api.NodeWithPeerInfo;
import codeine.api.ScehudleCommandExecutionInfo;
import codeine.configuration.Links;
import codeine.jsons.project.ProjectJson;
import codeine.permissions.IUserWithPermissions;
import codeine.utils.ThreadUtils;
public abstract class CommandExecutionStrategy {
private static final Logger log = Logger.getLogger(CommandExecutionStrategy.class);
private ScehudleCommandExecutionInfo commandData;
private AllNodesCommandExecuter allNodesCommandExecuter;
private Links links;
private boolean cancel;
private ProjectJson project;
private IUserWithPermissions userObject;
private String error;
public static final int MAX_NODES_TO_EXECUTE = 100;
public CommandExecutionStrategy(ScehudleCommandExecutionInfo commandData,
AllNodesCommandExecuter allNodesCommandExecuter, Links links, ProjectJson project, IUserWithPermissions userObject) {
super();
this.commandData = commandData;
this.allNodesCommandExecuter = allNodesCommandExecuter;
this.links = links;
this.project = project;
this.userObject = userObject;
}
public abstract void execute();
protected void writeLine(String message) {
allNodesCommandExecuter.writeLine(message);
}
private void commandNode(ExecutorService executor, NodeWithPeerInfo node, boolean shouldOutputImmediatly) {
PeerCommandWorker worker = new PeerCommandWorker(node, allNodesCommandExecuter, commandData.command_info(), shouldOutputImmediatly, links, project, userObject);
executor.execute(worker);
}
protected ScehudleCommandExecutionInfo commandData() {
return commandData;
}
protected void executeConcurrent(List<NodeWithPeerInfo> nodes, int concurrency) {
boolean shouldOutputImmediatly = concurrency < 2 || nodes.size() < 2;
if (concurrency > MAX_NODES_TO_EXECUTE) {
log.info("concurrency is above limit " + concurrency);
writeLine("concurrency is above limit, will reduce it to " + MAX_NODES_TO_EXECUTE);
concurrency = MAX_NODES_TO_EXECUTE;
}
ExecutorService executor = ThreadUtils.newFixedThreadPool(concurrency, "CommandExecution-" + allNodesCommandExecuter.commandString());
for (NodeWithPeerInfo peer : nodes) {
commandNode(executor, peer, shouldOutputImmediatly);
}
executor.shutdown();
while (!executor.isTerminated() && !isCancel()) {
try {
Thread.sleep(1000);
if (isCancel()) {
List<Runnable> shutdownNow = executor.shutdownNow();
log.info("shutdownNow " + shutdownNow.size());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public void setCancel() {
cancel = true;
}
public boolean isCancel(){
return cancel;
}
public boolean isError() {
return error != null;
}
public String error() {
return error;
}
protected void error(String error) {
this.error = error;
}
protected AllNodesCommandExecuter allNodesCommandExecuter() {
return allNodesCommandExecuter;
}
}