use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.
the class CommandProcessor method start.
/**
* Start executor.
*/
public void start() {
ctx.io().addMessageListener(GridTopic.TOPIC_QUERY, (nodeId, msg, plc) -> onMessage(nodeId, msg));
ctx.event().addLocalEventListener(new GridLocalEventListener() {
@Override
public void onEvent(final Event evt) {
UUID nodeId = ((DiscoveryEvent) evt).eventNode().id();
List<GridFutureAdapter<String>> futs = new ArrayList<>();
lock.writeLock().lock();
try {
Iterator<KillQueryRun> it = cancellationRuns.values().iterator();
while (it.hasNext()) {
KillQueryRun qryRun = it.next();
if (qryRun.nodeId().equals(nodeId)) {
futs.add(qryRun.cancelFuture());
it.remove();
}
}
} finally {
lock.writeLock().unlock();
}
futs.forEach(f -> f.onDone("Query node has left the grid: [nodeId=" + nodeId + "]"));
}
}, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
}
use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.
the class IgniteUtilsSelfTest method runTask.
/**
* @param executorService Executor service.
*/
private void runTask(ExecutorService executorService) {
List<Integer> data = asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
long threadId = Thread.currentThread().getId();
AtomicInteger curThreadCnt = new AtomicInteger();
Collection<Integer> res;
// Future for avoiding fast execution in only executor threads.
// Here we try to pass a number of tasks more that executor size,
// but there is a case when all task will be completed after last submit return control and
// current thread can not steal task because all task will be already finished.
GridFutureAdapter fut = new GridFutureAdapter();
try {
res = U.doInParallel(10, executorService, data, new IgniteThrowableFunction<Integer, Integer>() {
@Override
public Integer apply(Integer cnt) {
if (Thread.currentThread().getId() == threadId) {
fut.onDone();
curThreadCnt.incrementAndGet();
} else {
try {
fut.get();
} catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
return -cnt;
}
});
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
Assert.assertTrue(curThreadCnt.get() > 0);
Assert.assertEquals(asList(0, -1, -2, -3, -4, -5, -6, -7, -8, -9), res);
}
use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.
the class GridCachePartitionExchangeManager method onKernalStart0.
/** {@inheritDoc} */
@Override
protected void onKernalStart0(boolean reconnect) throws IgniteCheckedException {
super.onKernalStart0(reconnect);
ClusterNode loc = cctx.localNode();
long startTime = loc.metrics().getStartTime();
assert startTime > 0;
// Generate dummy discovery event for local node joining.
T2<DiscoveryEvent, DiscoCache> locJoin = cctx.discovery().localJoin();
DiscoveryEvent discoEvt = locJoin.get1();
DiscoCache discoCache = locJoin.get2();
GridDhtPartitionExchangeId exchId = initialExchangeId();
GridDhtPartitionsExchangeFuture fut = exchangeFuture(exchId, discoEvt, discoCache, null, null);
if (reconnect)
reconnectExchangeFut = new GridFutureAdapter<>();
exchWorker.addFirstExchangeFuture(fut);
if (!cctx.kernalContext().clientNode()) {
for (int cnt = 0; cnt < cctx.gridConfig().getRebalanceThreadPoolSize(); cnt++) {
final int idx = cnt;
cctx.io().addOrderedHandler(rebalanceTopic(cnt), new CI2<UUID, GridCacheMessage>() {
@Override
public void apply(final UUID id, final GridCacheMessage m) {
if (!enterBusy())
return;
try {
GridCacheContext cacheCtx = cctx.cacheContext(m.cacheId);
if (cacheCtx != null) {
if (m instanceof GridDhtPartitionSupplyMessage)
cacheCtx.preloader().handleSupplyMessage(idx, id, (GridDhtPartitionSupplyMessage) m);
else if (m instanceof GridDhtPartitionDemandMessage)
cacheCtx.preloader().handleDemandMessage(idx, id, (GridDhtPartitionDemandMessage) m);
else
U.error(log, "Unsupported message type: " + m.getClass().getName());
}
} finally {
leaveBusy();
}
}
});
}
}
new IgniteThread(cctx.igniteInstanceName(), "exchange-worker", exchWorker).start();
if (reconnect) {
fut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
try {
fut.get();
for (GridCacheContext cacheCtx : cctx.cacheContexts()) cacheCtx.preloader().onInitialExchangeComplete(null);
reconnectExchangeFut.onDone();
} catch (IgniteCheckedException e) {
for (GridCacheContext cacheCtx : cctx.cacheContexts()) cacheCtx.preloader().onInitialExchangeComplete(e);
reconnectExchangeFut.onDone(e);
}
}
});
} else {
if (log.isDebugEnabled())
log.debug("Beginning to wait on local exchange future: " + fut);
boolean first = true;
while (true) {
try {
fut.get(cctx.preloadExchangeTimeout());
break;
} catch (IgniteFutureTimeoutCheckedException ignored) {
if (first) {
U.warn(log, "Failed to wait for initial partition map exchange. " + "Possible reasons are: " + U.nl() + " ^-- Transactions in deadlock." + U.nl() + " ^-- Long running transactions (ignore if this is the case)." + U.nl() + " ^-- Unreleased explicit locks.");
first = false;
} else
U.warn(log, "Still waiting for initial partition map exchange [fut=" + fut + ']');
} catch (IgniteNeedReconnectException e) {
throw e;
} catch (Exception e) {
if (fut.reconnectOnError(e))
throw new IgniteNeedReconnectException(cctx.localNode(), e);
throw e;
}
}
AffinityTopologyVersion nodeStartVer = new AffinityTopologyVersion(discoEvt.topologyVersion(), 0);
for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
if (nodeStartVer.equals(cacheCtx.startTopologyVersion()))
cacheCtx.preloader().onInitialExchangeComplete(null);
}
if (log.isDebugEnabled())
log.debug("Finished waiting for initial exchange: " + fut.exchangeId());
}
}
use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.
the class GridAffinityProcessor method affinityCache.
/**
* @param cacheName Cache name.
* @param topVer Topology version.
* @return Affinity cache.
* @throws IgniteCheckedException In case of error.
*/
@SuppressWarnings("ErrorNotRethrown")
@Nullable
private AffinityInfo affinityCache(final String cacheName, AffinityTopologyVersion topVer) throws IgniteCheckedException {
AffinityAssignmentKey key = new AffinityAssignmentKey(cacheName, topVer);
IgniteInternalFuture<AffinityInfo> fut = affMap.get(key);
if (fut != null)
return fut.get();
GridCacheAdapter<Object, Object> cache = ctx.cache().internalCache(cacheName);
if (cache != null) {
GridCacheContext<Object, Object> cctx = cache.context();
cctx.awaitStarted();
AffinityAssignment assign0 = cctx.affinity().assignment(topVer);
try {
cctx.gate().enter();
} catch (IllegalStateException ignored) {
return null;
}
try {
GridAffinityAssignment assign = assign0 instanceof GridAffinityAssignment ? (GridAffinityAssignment) assign0 : new GridAffinityAssignment(topVer, assign0.assignment(), assign0.idealAssignment());
AffinityInfo info = new AffinityInfo(cctx.config().getAffinity(), cctx.config().getAffinityMapper(), assign, cctx.cacheObjectContext());
IgniteInternalFuture<AffinityInfo> old = affMap.putIfAbsent(key, new GridFinishedFuture<>(info));
if (old != null)
info = old.get();
return info;
} finally {
cctx.gate().leave();
}
}
Collection<ClusterNode> cacheNodes = ctx.discovery().cacheNodes(cacheName, topVer);
if (F.isEmpty(cacheNodes))
return null;
GridFutureAdapter<AffinityInfo> fut0 = new GridFutureAdapter<>();
IgniteInternalFuture<AffinityInfo> old = affMap.putIfAbsent(key, fut0);
if (old != null)
return old.get();
int max = ERROR_RETRIES;
int cnt = 0;
Iterator<ClusterNode> it = cacheNodes.iterator();
// We are here because affinity has not been fetched yet, or cache mode is LOCAL.
while (true) {
cnt++;
if (!it.hasNext())
it = cacheNodes.iterator();
// Double check since we deal with dynamic view.
if (!it.hasNext())
// Exception will be caught in this method.
throw new IgniteCheckedException("No cache nodes in topology for cache name: " + cacheName);
ClusterNode n = it.next();
CacheMode mode = ctx.cache().cacheMode(cacheName);
if (mode == null) {
if (ctx.clientDisconnected())
throw new IgniteClientDisconnectedCheckedException(ctx.cluster().clientReconnectFuture(), "Failed to get affinity mapping, client disconnected.");
throw new IgniteCheckedException("No cache nodes in topology for cache name: " + cacheName);
}
// Map all keys to a single node, if the cache mode is LOCAL.
if (mode == LOCAL) {
fut0.onDone(new IgniteCheckedException("Failed to map keys for LOCAL cache."));
// Will throw exception.
fut0.get();
}
try {
// Resolve cache context for remote node.
// Set affinity function before counting down on latch.
fut0.onDone(affinityInfoFromNode(cacheName, topVer, n));
break;
} catch (IgniteCheckedException e) {
if (log.isDebugEnabled())
log.debug("Failed to get affinity from node (will retry) [cache=" + cacheName + ", node=" + U.toShortString(n) + ", msg=" + e.getMessage() + ']');
if (cnt < max) {
U.sleep(ERROR_WAIT);
continue;
}
affMap.remove(key, fut0);
fut0.onDone(new IgniteCheckedException("Failed to get affinity mapping from node: " + n, e));
break;
} catch (RuntimeException | Error e) {
fut0.onDone(new IgniteCheckedException("Failed to get affinity mapping from node: " + n, e));
break;
}
}
return fut0.get();
}
use of org.apache.ignite.internal.util.future.GridFutureAdapter in project ignite by apache.
the class IgfsDataManager method dataBlock.
/**
* Get data block for specified file ID and block index.
*
* @param fileInfo File info.
* @param path Path reading from.
* @param blockIdx Block index.
* @param secReader Optional secondary file system reader.
* @return Requested data block or {@code null} if nothing found.
* @throws IgniteCheckedException If failed.
*/
@Nullable
public IgniteInternalFuture<byte[]> dataBlock(final IgfsEntryInfo fileInfo, final IgfsPath path, final long blockIdx, @Nullable final IgfsSecondaryFileSystemPositionedReadable secReader) throws IgniteCheckedException {
assert fileInfo != null;
assert blockIdx >= 0;
// Schedule block request BEFORE prefetch requests.
final IgfsBlockKey key = blockKey(blockIdx, fileInfo);
if (log.isDebugEnabled() && dataCache.affinity().isPrimaryOrBackup(igfsCtx.kernalContext().discovery().localNode(), key)) {
log.debug("Reading non-local data block [path=" + path + ", fileInfo=" + fileInfo + ", blockIdx=" + blockIdx + ']');
}
IgniteInternalFuture<byte[]> fut = dataCachePrj.getAsync(key);
if (secReader != null) {
Executor exec = igfsCtx.kernalContext().pools().poolForPolicy(GridIoPolicy.IGFS_POOL);
fut = fut.chain(new CX1<IgniteInternalFuture<byte[]>, byte[]>() {
@Override
public byte[] applyx(IgniteInternalFuture<byte[]> fut) throws IgniteCheckedException {
byte[] res = fut.get();
if (res == null) {
GridFutureAdapter<byte[]> rmtReadFut = new GridFutureAdapter<>();
IgniteInternalFuture<byte[]> oldRmtReadFut = rmtReadFuts.putIfAbsent(key, rmtReadFut);
if (oldRmtReadFut == null) {
try {
res = secondaryDataBlock(path, blockIdx, secReader, fileInfo.blockSize());
rmtReadFut.onDone(res);
putBlock(fileInfo.blockSize(), key, res);
} catch (IgniteCheckedException e) {
rmtReadFut.onDone(e);
throw e;
} finally {
boolean rmv = rmtReadFuts.remove(key, rmtReadFut);
assert rmv;
}
} else {
// Wait for existing future to finish and get it's result.
res = oldRmtReadFut.get();
igfsCtx.metrics().addReadBlocks(1, 0);
}
} else
igfsCtx.metrics().addReadBlocks(1, 0);
return res;
}
}, exec);
} else
igfsCtx.metrics().addReadBlocks(1, 0);
return fut;
}
Aggregations