use of org.apache.ignite.internal.processors.timeout.GridTimeoutObject in project ignite by apache.
the class GridDhtPartitionDemander method addAssignments.
/**
* Initiates new rebalance process from given {@code assignments}.
* If previous rebalance is not finished method cancels it.
* In case of delayed rebalance method schedules new with configured delay.
*
* @param assignments Assignments.
* @param force {@code True} if dummy reassign.
* @param rebalanceId Rebalance id.
* @param next Runnable responsible for cache rebalancing start.
* @param forcedRebFut External future for forced rebalance.
* @return Rebalancing runnable.
*/
Runnable addAssignments(final GridDhtPreloaderAssignments assignments, boolean force, long rebalanceId, final Runnable next, @Nullable final GridCompoundFuture<Boolean, Boolean> forcedRebFut) {
if (log.isDebugEnabled())
log.debug("Adding partition assignments: " + assignments);
assert force == (forcedRebFut != null);
long delay = grp.config().getRebalanceDelay();
if ((delay == 0 || force) && assignments != null) {
final RebalanceFuture oldFut = rebalanceFut;
final RebalanceFuture fut = new RebalanceFuture(grp, assignments, log, rebalanceId);
if (!oldFut.isInitial())
oldFut.cancel();
else
fut.listen(f -> oldFut.onDone(f.result()));
if (forcedRebFut != null)
forcedRebFut.add(fut);
rebalanceFut = fut;
for (final GridCacheContext cctx : grp.caches()) {
if (cctx.statisticsEnabled()) {
final CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.clearRebalanceCounters();
metrics.startRebalance(0);
rebalanceFut.listen(f -> metrics.clearRebalanceCounters());
}
}
fut.sendRebalanceStartedEvent();
if (assignments.cancelled()) {
// Pending exchange.
if (log.isDebugEnabled())
log.debug("Rebalancing skipped due to cancelled assignments.");
fut.onDone(false);
fut.sendRebalanceFinishedEvent();
return null;
}
if (assignments.isEmpty()) {
// Nothing to rebalance.
if (log.isDebugEnabled())
log.debug("Rebalancing skipped due to empty assignments.");
fut.onDone(true);
((GridFutureAdapter) grp.preloader().syncFuture()).onDone();
fut.sendRebalanceFinishedEvent();
return null;
}
return () -> {
if (next != null)
fut.listen(f -> {
try {
if (// Not cancelled.
f.get())
// Starts next cache rebalancing (according to the order).
next.run();
} catch (IgniteCheckedException e) {
if (log.isDebugEnabled())
log.debug(e.getMessage());
}
});
requestPartitions(fut, assignments);
};
} else if (delay > 0) {
for (GridCacheContext cctx : grp.caches()) {
if (cctx.statisticsEnabled()) {
final CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.startRebalance(delay);
}
}
GridTimeoutObject obj = lastTimeoutObj.get();
if (obj != null)
ctx.time().removeTimeoutObject(obj);
final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
assert exchFut != null : "Delaying rebalance process without topology event.";
obj = new GridTimeoutObjectAdapter(delay) {
@Override
public void onTimeout() {
exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> f) {
ctx.exchange().forceRebalance(exchFut.exchangeId());
}
});
}
};
lastTimeoutObj.set(obj);
ctx.time().addTimeoutObject(obj);
}
return null;
}
use of org.apache.ignite.internal.processors.timeout.GridTimeoutObject in project ignite by apache.
the class GridDhtPartitionDemander method addAssignments.
/**
* This method initiates new rebalance process from given {@code assignments} by creating new rebalance
* future based on them. Cancels previous rebalance future and sends rebalance started event.
* In case of delayed rebalance method schedules the new one with configured delay based on {@code lastExchangeFut}.
*
* @param assignments Assignments to process.
* @param force {@code True} if preload request by {@link ForceRebalanceExchangeTask}.
* @param rebalanceId Rebalance id generated from exchange thread.
* @param next A next rebalance routine in chain.
* @param forcedRebFut External future for forced rebalance.
* @param compatibleRebFut Future for waiting for compatible rebalances.
*
* @return Rebalancing future or {@code null} to exclude an assignment from a chain.
*/
@Nullable
RebalanceFuture addAssignments(final GridDhtPreloaderAssignments assignments, boolean force, long rebalanceId, final RebalanceFuture next, @Nullable final GridCompoundFuture<Boolean, Boolean> forcedRebFut, GridCompoundFuture<Boolean, Boolean> compatibleRebFut) {
if (log.isDebugEnabled())
log.debug("Adding partition assignments: " + assignments);
assert force == (forcedRebFut != null);
long delay = grp.config().getRebalanceDelay();
if (delay == 0 || force) {
assert assignments != null;
final RebalanceFuture oldFut = rebalanceFut;
if (assignments.cancelled()) {
// Pending exchange.
if (log.isDebugEnabled())
log.debug("Rebalancing skipped due to cancelled assignments.");
return null;
}
if (assignments.isEmpty()) {
// Nothing to rebalance.
if (log.isDebugEnabled())
log.debug("Rebalancing skipped due to empty assignments.");
if (oldFut.isInitial())
oldFut.onDone(true);
else if (!oldFut.isDone())
oldFut.tryCancel();
((GridFutureAdapter) grp.preloader().syncFuture()).onDone();
return null;
}
// Check if ongoing rebalancing is compatible with a new assignment.
if (!force && (!oldFut.isDone() || oldFut.result()) && oldFut.compatibleWith(assignments)) {
if (!oldFut.isDone())
compatibleRebFut.add(oldFut);
return null;
}
// Cancel ongoing rebalancing.
if (!oldFut.isDone() && !oldFut.isInitial())
oldFut.tryCancel();
// Partition states cannot be changed from now on by previous incompatible rebalancing.
// Retain only moving partitions. Assignment can become empty as a result.
// Delayed partition owning happens in the exchange worker as well, so no race with delayed owning here.
assignments.retainMoving(grp.topology());
// Skip rebalanced group.
if (assignments.isEmpty())
return null;
final RebalanceFuture fut = new RebalanceFuture(grp, lastExchangeFut, assignments, log, rebalanceId, next, lastCancelledTime);
if (oldFut.isInitial())
fut.listen(f -> oldFut.onDone(f.result()));
if (forcedRebFut != null)
forcedRebFut.add(fut);
rebalanceFut = fut;
for (final GridCacheContext cctx : grp.caches()) {
if (cctx.statisticsEnabled()) {
final CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.clearRebalanceCounters();
for (GridDhtPartitionDemandMessage msg : assignments.values()) {
for (Integer partId : msg.partitions().fullSet()) metrics.onRebalancingKeysCountEstimateReceived(grp.topology().globalPartSizes().get(partId));
CachePartitionPartialCountersMap histMap = msg.partitions().historicalMap();
for (int i = 0; i < histMap.size(); i++) {
long from = histMap.initialUpdateCounterAt(i);
long to = histMap.updateCounterAt(i);
metrics.onRebalancingKeysCountEstimateReceived(to - from);
}
}
metrics.startRebalance(0);
}
}
fut.sendRebalanceStartedEvent();
return fut;
} else if (delay > 0) {
for (GridCacheContext cctx : grp.caches()) {
if (cctx.statisticsEnabled()) {
final CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.startRebalance(delay);
}
}
GridTimeoutObject obj = lastTimeoutObj.get();
if (obj != null)
ctx.time().removeTimeoutObject(obj);
final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
assert exchFut != null : "Delaying rebalance process without topology event.";
obj = new GridTimeoutObjectAdapter(delay) {
@Override
public void onTimeout() {
exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> f) {
ctx.exchange().forceRebalance(exchFut.exchangeId());
}
});
}
};
lastTimeoutObj.set(obj);
ctx.time().addTimeoutObject(obj);
}
return null;
}
use of org.apache.ignite.internal.processors.timeout.GridTimeoutObject in project ignite by apache.
the class GridDhtAtomicCache method sendDeferredUpdateResponse.
/**
* @param primaryId Primary ID.
* @param msg Message.
*/
private void sendDeferredUpdateResponse(UUID primaryId, GridDhtAtomicDeferredUpdateResponse msg) {
try {
GridTimeoutObject timeoutSnd = msg.timeoutSender();
if (timeoutSnd != null)
ctx.time().removeTimeoutObject(timeoutSnd);
ctx.io().send(primaryId, msg, ctx.ioPolicy());
if (msgLog.isDebugEnabled()) {
msgLog.debug("Sent deferred DHT update response [futIds=" + msg.futureIds() + ", node=" + primaryId + ']');
}
} catch (ClusterTopologyCheckedException ignored) {
if (msgLog.isDebugEnabled()) {
msgLog.debug("Failed to send deferred DHT update response, node left [" + "futIds=" + msg.futureIds() + ", node=" + primaryId + ']');
}
} catch (IgniteCheckedException e) {
U.error(log, "Failed to send deferredDHT update response to remote node [" + "futIds=" + msg.futureIds() + ", node=" + primaryId + ']', e);
}
}
use of org.apache.ignite.internal.processors.timeout.GridTimeoutObject in project ignite by apache.
the class GridJobContextImpl method holdcc.
/**
* {@inheritDoc}
*/
@Override
public <T> T holdcc(long timeout) {
if (ctx != null) {
if (job == null)
job = ctx.job().activeJob(jobId);
if (job != null) {
if (!job.hold())
throw new IllegalStateException("Job has already been hold [ctx=" + this + ']');
assert timeoutObj == null;
if (timeout <= 0)
return null;
final long endTime = U.currentTimeMillis() + timeout;
// Overflow.
if (endTime > 0) {
timeoutObj = new GridTimeoutObject() {
private final IgniteUuid id = IgniteUuid.randomUuid();
@Override
public IgniteUuid timeoutId() {
return id;
}
@Override
public long endTime() {
return endTime;
}
@Override
public void onTimeout() {
try {
synchronized (mux) {
GridTimeoutObject timeoutObj0 = timeoutObj;
if (timeoutObj0 == null || timeoutObj0.timeoutId() != id)
// The timer was canceled by explicit callcc() call.
return;
timeoutObj = null;
}
ExecutorService execSvc = job.isInternal() ? ctx.pools().getManagementExecutorService() : ctx.pools().getExecutorService();
assert execSvc != null;
execSvc.execute(new Runnable() {
@Override
public void run() {
callcc0();
}
});
} catch (RejectedExecutionException e) {
U.error(log(), "Failed to execute job (will execute synchronously).", e);
callcc0();
}
}
};
ctx.timeout().addTimeoutObject(timeoutObj);
}
}
}
return null;
}
use of org.apache.ignite.internal.processors.timeout.GridTimeoutObject in project ignite by apache.
the class StartNodeCallableImpl method shell.
/**
* Executes command using {@code shell} channel.
*
* @param ses SSH session.
* @param cmd Command.
* @param regexp Regular expression to wait until it will be found in stream from node.
* @throws JSchException In case of SSH error.
* @throws IOException If IO error occurs.
* @throws IgniteInterruptedCheckedException If thread was interrupted while waiting.
*/
private void shell(Session ses, String cmd, String regexp) throws JSchException, IOException, IgniteInterruptedCheckedException {
ChannelShell ch = null;
GridTimeoutObject to = null;
try {
ch = (ChannelShell) ses.openChannel("shell");
ch.connect();
try (PrintStream out = new PrintStream(ch.getOutputStream(), true)) {
out.println(cmd);
}
if (regexp != null) {
Pattern ptrn = Pattern.compile(regexp);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(ch.getInputStream()))) {
String line;
boolean first = true;
while ((line = reader.readLine()) != null) {
if (ptrn.matcher(line).find()) {
// Wait for a while until process from regexp really will be started.
U.sleep(50);
break;
} else if (first) {
to = initTimer(cmd);
first = false;
}
}
} catch (InterruptedIOException ignore) {
// No-op.
} finally {
if (to != null) {
boolean r = proc.removeTimeoutObject(to);
assert r || to.endTime() <= U.currentTimeMillis() : "Timeout object was not removed: " + to;
}
}
} else
U.sleep(EXECUTE_WAIT_TIME);
} finally {
if (ch != null && ch.isConnected())
ch.disconnect();
}
}
Aggregations