use of org.apache.ignite.IgniteClientDisconnectedException in project ignite by apache.
the class GridReduceQueryExecutor method query.
/**
* @param qryId Query ID.
* @param schemaName Schema name.
* @param qry Query.
* @param keepBinary Keep binary.
* @param enforceJoinOrder Enforce join order of tables.
* @param timeoutMillis Timeout in milliseconds.
* @param cancel Query cancel.
* @param params Query parameters.
* @param parts Partitions.
* @param lazy Lazy execution flag.
* @param mvccTracker Query tracker.
* @param dataPageScanEnabled If data page scan is enabled.
* @param pageSize Page size.
* @return Rows iterator.
*/
@SuppressWarnings("IfMayBeConditional")
public Iterator<List<?>> query(long qryId, String schemaName, final GridCacheTwoStepQuery qry, boolean keepBinary, boolean enforceJoinOrder, int timeoutMillis, GridQueryCancel cancel, Object[] params, int[] parts, boolean lazy, MvccQueryTracker mvccTracker, Boolean dataPageScanEnabled, int pageSize) {
assert !qry.mvccEnabled() || mvccTracker != null;
if (pageSize <= 0)
pageSize = Query.DFLT_PAGE_SIZE;
// If explicit partitions are set, but there are no real tables, ignore.
if (!qry.hasCacheIds() && parts != null)
parts = null;
// Partitions are not supported for queries over all replicated caches.
if (parts != null && qry.isReplicatedOnly())
throw new CacheException("Partitions are not supported for replicated caches");
try {
if (qry.mvccEnabled())
checkActive(tx(ctx));
} catch (IgniteTxAlreadyCompletedCheckedException e) {
throw new TransactionAlreadyCompletedException(e.getMessage(), e);
}
final boolean singlePartMode = parts != null && parts.length == 1;
if (F.isEmpty(params))
params = EMPTY_PARAMS;
List<Integer> cacheIds = qry.cacheIds();
List<GridCacheSqlQuery> mapQueries = prepareMapQueries(qry, params, singlePartMode);
final boolean skipMergeTbl = !qry.explain() && qry.skipMergeTable() || singlePartMode;
final long retryTimeout = retryTimeout(timeoutMillis);
final long qryStartTime = U.currentTimeMillis();
ReduceQueryRun lastRun = null;
for (int attempt = 0; ; attempt++) {
ensureQueryNotCancelled(cancel);
if (attempt > 0) {
throttleOnRetry(lastRun, qryStartTime, retryTimeout, attempt);
ensureQueryNotCancelled(cancel);
}
AffinityTopologyVersion topVer = h2.readyTopologyVersion();
// Check if topology has changed while retrying on locked topology.
if (h2.serverTopologyChanged(topVer) && ctx.cache().context().lockedTopologyVersion(null) != null) {
throw new CacheException(new TransactionException("Server topology is changed during query " + "execution inside a transaction. It's recommended to rollback and retry transaction."));
}
ReducePartitionMapResult mapping = createMapping(qry, parts, cacheIds, topVer);
if (// Can't map query.
mapping == null)
// Retry.
continue;
final Collection<ClusterNode> nodes = mapping.nodes();
final Map<ClusterNode, Integer> nodeToSegmentsCnt = createNodeToSegmentsCountMapping(qry, mapping);
assert !F.isEmpty(nodes);
H2PooledConnection conn = h2.connections().connection(schemaName);
final long qryReqId = qryReqIdGen.incrementAndGet();
h2.runningQueryManager().trackRequestId(qryReqId);
boolean release = true;
try {
final ReduceQueryRun r = createReduceQueryRun(conn, mapQueries, nodes, pageSize, nodeToSegmentsCnt, skipMergeTbl, qry.explain(), dataPageScanEnabled);
runs.put(qryReqId, r);
try {
cancel.add(() -> send(nodes, new GridQueryCancelRequest(qryReqId), null, true));
GridH2QueryRequest req = new GridH2QueryRequest().queryId(qryId).requestId(qryReqId).topologyVersion(topVer).pageSize(pageSize).caches(qry.cacheIds()).tables(qry.distributedJoins() ? qry.tables() : null).partitions(convert(mapping.partitionsMap())).queries(mapQueries).parameters(params).flags(queryFlags(qry, enforceJoinOrder, lazy, dataPageScanEnabled)).timeout(timeoutMillis).explicitTimeout(true).schemaName(schemaName);
if (mvccTracker != null)
req.mvccSnapshot(mvccTracker.snapshot());
final C2<ClusterNode, Message, Message> spec = parts == null ? null : new ReducePartitionsSpecializer(mapping.queryPartitionsMap());
boolean retry = false;
if (send(nodes, req, spec, false)) {
awaitAllReplies(r, nodes, cancel);
if (r.hasErrorOrRetry()) {
CacheException err = r.exception();
if (err != null) {
if (err.getCause() instanceof IgniteClientDisconnectedException)
throw err;
else if (QueryUtils.wasCancelled(err))
// Throw correct exception.
throw new QueryCancelledException();
throw err;
}
// If remote node asks us to retry then we have outdated full partition map.
h2.awaitForReadyTopologyVersion(r.retryTopologyVersion());
retry = true;
}
} else
retry = true;
if (retry) {
lastRun = runs.get(qryReqId);
assert lastRun != null;
// Retry.
continue;
}
Iterator<List<?>> resIter;
if (skipMergeTbl) {
resIter = new ReduceIndexIterator(this, nodes, r, qryReqId, qry.distributedJoins(), mvccTracker, ctx.tracing());
release = false;
U.close(conn, log);
} else {
ensureQueryNotCancelled(cancel);
QueryContext qctx = new QueryContext(0, null, null, null, null, true);
H2Utils.setupConnection(conn, qctx, false, enforceJoinOrder);
if (qry.explain())
return explainPlan(conn, qry, params);
GridCacheSqlQuery rdc = qry.reduceQuery();
final PreparedStatement stmt = conn.prepareStatementNoCache(rdc.query());
H2Utils.bindParameters(stmt, F.asList(rdc.parameters(params)));
ReduceH2QueryInfo qryInfo = new ReduceH2QueryInfo(stmt, qry.originalSql(), ctx.localNodeId(), qryId, qryReqId);
ResultSet res = h2.executeSqlQueryWithTimer(stmt, conn, rdc.query(), timeoutMillis, cancel, dataPageScanEnabled, qryInfo);
resIter = new H2FieldsIterator(res, mvccTracker, conn, r.pageSize(), log, h2, qryInfo, ctx.tracing());
conn = null;
// To prevent callback inside finally block;
mvccTracker = null;
}
return new GridQueryCacheObjectsIterator(resIter, h2.objectContext(), keepBinary);
} catch (IgniteCheckedException | RuntimeException e) {
release = true;
if (e instanceof CacheException) {
if (QueryUtils.wasCancelled(e))
throw new CacheException("Failed to run reduce query locally.", new QueryCancelledException());
throw (CacheException) e;
}
Throwable cause = e;
if (e instanceof IgniteCheckedException) {
Throwable disconnectedErr = ((IgniteCheckedException) e).getCause(IgniteClientDisconnectedException.class);
if (disconnectedErr != null)
cause = disconnectedErr;
}
throw new CacheException("Failed to run reduce query locally. " + cause.getMessage(), cause);
} finally {
if (release) {
releaseRemoteResources(nodes, r, qryReqId, qry.distributedJoins(), mvccTracker);
if (!skipMergeTbl) {
for (int i = 0, mapQrys = mapQueries.size(); i < mapQrys; i++) // Drop all merge tables.
fakeTable(null, i).innerTable(null);
}
}
}
} finally {
if (conn != null && release)
U.close(conn, log);
}
}
}
use of org.apache.ignite.IgniteClientDisconnectedException in project ignite by apache.
the class WebSessionFilter method handleCacheOperationException.
/**
* Handles cache operation exception.
* @param e Exception
*/
void handleCacheOperationException(Exception e) {
IgniteFuture<?> retryFut = null;
if (e instanceof IllegalStateException) {
initCache();
return;
} else if (X.hasCause(e, IgniteClientDisconnectedException.class)) {
IgniteClientDisconnectedException cause = X.cause(e, IgniteClientDisconnectedException.class);
assert cause != null : e;
retryFut = cause.reconnectFuture();
} else if (X.hasCause(e, ClusterTopologyException.class)) {
ClusterTopologyException cause = X.cause(e, ClusterTopologyException.class);
assert cause != null : e;
retryFut = cause.retryReadyFuture();
}
if (retryFut != null) {
try {
retryFut.get(retriesTimeout);
} catch (IgniteException retryErr) {
throw new IgniteException("Failed to wait for retry: " + retryErr);
}
}
}
use of org.apache.ignite.IgniteClientDisconnectedException in project ignite by apache.
the class IgniteCacheContinuousQueryReconnectTest method testReconnect.
/**
* @throws Exception If failed.
*/
private void testReconnect(boolean clientQuery) throws Exception {
Ignite srv1 = startGrid(0);
ContinuousQuery<Object, Object> qry = new ContinuousQuery<>();
qry.setLocalListener(new CacheEntryUpdatedListener<Object, Object>() {
@Override
public void onUpdated(Iterable iterable) throws CacheEntryListenerException {
// No-op.
}
});
qry.setAutoUnsubscribe(false);
qry.setRemoteFilter(new CacheEntryEventSerializableFilter<Object, Object>() {
@Override
public boolean evaluate(CacheEntryEvent<?, ?> event) throws CacheEntryListenerException {
cnt.incrementAndGet();
return true;
}
});
Ignite client = startClientGrid(1);
IgniteCache<Object, Object> cache1 = srv1.cache(DEFAULT_CACHE_NAME);
IgniteCache<Object, Object> clCache = client.cache(DEFAULT_CACHE_NAME);
// 0 remote listeners.
putAndCheck(clCache, 0);
(clientQuery ? clCache : cache1).query(qry);
// 1 remote listener.
putAndCheck(clCache, 1);
startGrid(2);
// 2 remote listeners.
putAndCheck(clCache, 2);
stopGrid(0);
while (true) {
try {
clCache.get(1);
break;
} catch (IgniteClientDisconnectedException e) {
// Wait for reconnect.
e.reconnectFuture().get();
} catch (CacheException e) {
if (e.getCause() instanceof IgniteClientDisconnectedException)
// Wait for reconnect.
((IgniteClientDisconnectedException) e.getCause()).reconnectFuture().get();
}
}
// 1 remote listener.
putAndCheck(clCache, 1);
startGrid(3);
// 2 remote listeners.
putAndCheck(clCache, 2);
// Client node.
stopGrid(1);
client = startClientGrid(4);
clCache = client.cache(DEFAULT_CACHE_NAME);
// 2 remote listeners.
putAndCheck(clCache, 2);
startGrid(5);
// 3 remote listeners.
putAndCheck(clCache, 3);
}
use of org.apache.ignite.IgniteClientDisconnectedException in project ignite by apache.
the class IgniteClientReconnectCacheTest method testReconnect.
/**
* @throws Exception If failed.
*/
@Test
public void testReconnect() throws Exception {
IgniteEx client = startClientGrid(SRV_CNT);
final IgniteDiscoverySpi clientSpi = spi0(client);
Ignite srv = ignite(0);
DiscoverySpi srvSpi = ignite(0).configuration().getDiscoverySpi();
final IgniteCache<Object, Object> cache = client.getOrCreateCache(new CacheConfiguration<>(DEFAULT_CACHE_NAME)).withAllowAtomicOpsInTx();
final IgniteCache<Object, Object> staticCache = client.cache(STATIC_CACHE).withAllowAtomicOpsInTx();
staticCache.put(1, 1);
assertEquals(1, staticCache.get(1));
CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME);
ccfg.setWriteSynchronizationMode(FULL_SYNC);
ccfg.setName(NEAR_CACHE_NAME);
final IgniteCache<Object, Object> nearCache = client.getOrCreateCache(ccfg, new NearCacheConfiguration<>()).withAllowAtomicOpsInTx();
nearCache.put(1, 1);
assertEquals(1, nearCache.localPeek(1));
cache.put(1, 1);
final CountDownLatch disconnectLatch = new CountDownLatch(1);
final CountDownLatch reconnectLatch = new CountDownLatch(1);
log.info("Block reconnect.");
DiscoverySpiTestListener lsnr = new DiscoverySpiTestListener();
clientSpi.setInternalListener(lsnr);
lsnr.startBlockJoin();
final AtomicReference<IgniteInternalFuture> blockPutRef = new AtomicReference<>();
client.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED) {
info("Disconnected: " + evt);
assertEquals(1, reconnectLatch.getCount());
blockPutRef.set(GridTestUtils.runAsync(new Callable() {
@Override
public Object call() throws Exception {
log.info("Start put.");
try {
cache.put(2, 2);
fail();
} catch (CacheException e) {
log.info("Expected exception: " + e);
IgniteClientDisconnectedException e0 = (IgniteClientDisconnectedException) e.getCause();
e0.reconnectFuture().get();
}
cache.put(2, 2);
log.info("Finish put.");
return null;
}
}));
disconnectLatch.countDown();
} else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
info("Reconnected: " + evt);
assertEquals(0, disconnectLatch.getCount());
reconnectLatch.countDown();
}
return true;
}
}, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
log.info("Fail client.");
srvSpi.failNode(client.cluster().localNode().id(), null);
waitReconnectEvent(disconnectLatch);
IgniteInternalFuture putFut = blockPutRef.get();
assertNotDone(putFut);
U.sleep(5000);
assertNotDone(putFut);
log.info("Allow reconnect.");
lsnr.stopBlockJoin();
assertTrue(reconnectLatch.await(5000, MILLISECONDS));
checkCacheDiscoveryData(srv, client, DEFAULT_CACHE_NAME, true, true, false);
checkCacheDiscoveryData(srv, client, NEAR_CACHE_NAME, true, true, true);
checkCacheDiscoveryData(srv, client, STATIC_CACHE, true, true, false);
assertEquals(1, cache.get(1));
putFut.get();
assertEquals(2, cache.get(2));
cache.put(3, 3);
assertEquals(3, cache.get(3));
assertNull(nearCache.localPeek(1));
staticCache.put(10, 10);
assertEquals(10, staticCache.get(10));
nearCache.put(20, 20);
srv.cache(nearCache.getName()).put(20, 21);
assertEquals(21, nearCache.localPeek(20));
IgniteEx srv2 = startGrid(SRV_CNT + 1);
Integer key = primaryKey(srv2.cache(DEFAULT_CACHE_NAME));
cache.put(key, 4);
assertEquals(4, cache.get(key));
checkCacheDiscoveryData(srv2, client, DEFAULT_CACHE_NAME, true, true, false);
checkCacheDiscoveryData(srv2, client, NEAR_CACHE_NAME, true, true, true);
checkCacheDiscoveryData(srv2, client, STATIC_CACHE, true, true, false);
staticCache.put(20, 20);
assertEquals(20, staticCache.get(20));
for (int i = 0; i < 100; i++) {
srv.cache(nearCache.getName()).put(i, 22);
Object actual = nearCache.localPeek(i);
// null-values can be valid in such case.
if (actual == null) {
actual = nearCache.get(i);
assertEquals(22, actual);
actual = nearCache.localPeek(i);
}
assertEquals(22, actual);
}
}
use of org.apache.ignite.IgniteClientDisconnectedException in project ignite by apache.
the class IgniteClientReconnectCacheTest method testReconnectOperationInProgress.
/**
* @throws Exception If failed.
*/
@Test
public void testReconnectOperationInProgress() throws Exception {
IgniteEx client = startClientGrid(SRV_CNT);
client.events().localListen(new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED)
info("Client disconnected: " + evt);
else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED)
info("Client reconnected: " + evt);
return true;
}
}, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
IgniteInClosure<IgniteCache<Object, Object>> putOp = new CI1<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
while (true) {
try {
cache.put(1, 1);
break;
} catch (Exception e) {
if (e.getCause() instanceof IgniteClientDisconnectedException)
throw e;
else
MvccFeatureChecker.assertMvccWriteConflict(e);
}
}
}
};
IgniteInClosure<IgniteCache<Object, Object>> getOp = new CI1<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
cache.get(1);
}
};
IgniteInClosure<IgniteCache<Object, Object>> getAllOp = new CI1<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
cache.getAll(F.asSet(1, 2));
}
};
int cnt = 0;
for (CacheAtomicityMode atomicityMode : CacheAtomicityMode.values()) {
for (CacheWriteSynchronizationMode syncMode : CacheWriteSynchronizationMode.values()) {
CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME);
ccfg.setAtomicityMode(atomicityMode);
ccfg.setName("cache-" + cnt++);
ccfg.setWriteSynchronizationMode(syncMode);
if (syncMode != FULL_ASYNC) {
Class<?> cls = (ccfg.getAtomicityMode() == ATOMIC) ? GridNearAtomicUpdateResponse.class : GridNearTxPrepareResponse.class;
log.info("Test cache put [atomicity=" + atomicityMode + ", syncMode=" + syncMode + ']');
checkOperationInProgressFails(client, ccfg, cls, putOp);
client.destroyCache(ccfg.getName());
}
log.info("Test cache get [atomicity=" + atomicityMode + ", syncMode=" + syncMode + ']');
checkOperationInProgressFails(client, ccfg, GridNearSingleGetResponse.class, getOp);
checkOperationInProgressFails(client, ccfg, GridNearGetResponse.class, getAllOp);
client.destroyCache(ccfg.getName());
}
}
}
Aggregations