use of org.apache.ignite.internal.util.nodestart.StartNodeCallable in project ignite by apache.
the class IgniteClusterImpl method startNodesAsync0.
/**
* @param hosts Startup parameters.
* @param dflts Default values.
* @param restart Whether to stop existing nodes
* @param timeout Connection timeout in milliseconds.
* @param maxConn Number of parallel SSH connections to one host.
* @return Future with results.
* @see IgniteCluster#startNodes(java.util.Collection, java.util.Map, boolean, int, int)
*/
IgniteInternalFuture<Collection<ClusterStartNodeResult>> startNodesAsync0(Collection<Map<String, Object>> hosts, @Nullable Map<String, Object> dflts, boolean restart, int timeout, int maxConn) {
A.notNull(hosts, "hosts");
guard();
try {
IgniteSshHelper sshHelper = IgniteComponentType.SSH.create(false);
Map<String, Collection<IgniteRemoteStartSpecification>> specsMap = specifications(hosts, dflts);
Map<String, ConcurrentLinkedQueue<StartNodeCallable>> runMap = new HashMap<>();
int nodeCallCnt = 0;
for (String host : specsMap.keySet()) {
InetAddress addr;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
throw new IgniteCheckedException("Invalid host name: " + host, e);
}
Collection<? extends ClusterNode> neighbors = null;
if (addr.isLoopbackAddress())
neighbors = neighbors();
else {
for (Collection<ClusterNode> p : U.neighborhood(nodes()).values()) {
ClusterNode node = F.first(p);
if (node.<String>attribute(ATTR_IPS).contains(addr.getHostAddress())) {
neighbors = p;
break;
}
}
}
int startIdx = 1;
if (neighbors != null) {
if (restart && !neighbors.isEmpty()) {
try {
ctx.grid().compute(forNodes(neighbors)).execute(IgniteKillTask.class, false);
} catch (ClusterGroupEmptyException ignored) {
// No-op, nothing to restart.
}
} else
startIdx = neighbors.size() + 1;
}
ConcurrentLinkedQueue<StartNodeCallable> nodeRuns = new ConcurrentLinkedQueue<>();
runMap.put(host, nodeRuns);
for (IgniteRemoteStartSpecification spec : specsMap.get(host)) {
assert spec.host().equals(host);
for (int i = startIdx; i <= spec.nodes(); i++) {
nodeRuns.add(sshHelper.nodeStartCallable(spec, timeout));
nodeCallCnt++;
}
}
}
// If there is nothing to start, return finished future with empty result.
if (nodeCallCnt == 0)
return new GridFinishedFuture<Collection<ClusterStartNodeResult>>(Collections.<ClusterStartNodeResult>emptyList());
// Exceeding max line width for readability.
GridCompoundFuture<ClusterStartNodeResult, Collection<ClusterStartNodeResult>> fut = new GridCompoundFuture<>(CU.<ClusterStartNodeResult>objectsReducer());
AtomicInteger cnt = new AtomicInteger(nodeCallCnt);
// Limit maximum simultaneous connection number per host.
for (ConcurrentLinkedQueue<StartNodeCallable> queue : runMap.values()) {
for (int i = 0; i < maxConn; i++) {
if (!runNextNodeCallable(queue, fut, cnt))
break;
}
}
return fut;
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
} finally {
unguard();
}
}
use of org.apache.ignite.internal.util.nodestart.StartNodeCallable in project ignite by apache.
the class IgniteClusterImpl method runNextNodeCallable.
/**
* Runs next callable from host node start queue.
*
* @param queue Queue of tasks to poll from.
* @param comp Compound future that comprise all started node tasks.
* @param cnt Atomic counter to check if all futures are added to compound future.
* @return {@code True} if task was started, {@code false} if queue was empty.
*/
private boolean runNextNodeCallable(final ConcurrentLinkedQueue<StartNodeCallable> queue, final GridCompoundFuture<ClusterStartNodeResult, Collection<ClusterStartNodeResult>> comp, final AtomicInteger cnt) {
StartNodeCallable call = queue.poll();
if (call == null)
return false;
IgniteInternalFuture<ClusterStartNodeResult> fut = ctx.closure().callLocalSafe(call, true);
comp.add(fut);
if (cnt.decrementAndGet() == 0)
comp.markInitialized();
fut.listen(new CI1<IgniteInternalFuture<ClusterStartNodeResult>>() {
@Override
public void apply(IgniteInternalFuture<ClusterStartNodeResult> f) {
runNextNodeCallable(queue, comp, cnt);
}
});
return true;
}
Aggregations