use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class DynamicIndexAbstractConcurrentSelfTest method testConcurrentOperationsMultithreaded.
/**
* Make sure that contended operations on the same index from different nodes do not hang.
*
* @throws Exception If failed.
*/
public void testConcurrentOperationsMultithreaded() throws Exception {
// Start complex topology.
Ignition.start(serverConfiguration(1));
Ignition.start(serverConfiguration(2));
Ignition.start(serverConfiguration(3, true));
Ignite cli = Ignition.start(clientConfiguration(4));
createSqlCache(cli);
final AtomicBoolean stopped = new AtomicBoolean();
// Start several threads which will mess around indexes.
final QueryIndex idx = index(IDX_NAME_1, field(FIELD_NAME_1));
IgniteInternalFuture idxFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
boolean exists = false;
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
IgniteInternalFuture fut;
if (exists) {
fut = queryProcessor(node).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true);
exists = false;
} else {
fut = queryProcessor(node).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true);
exists = true;
}
try {
fut.get();
} catch (SchemaOperationException e) {
// No-op.
} catch (Exception e) {
fail("Unexpected exception: " + e);
}
}
return null;
}
}, 8);
Thread.sleep(TEST_DUR);
stopped.set(true);
// Make sure nothing hanged.
idxFut.get();
queryProcessor(cli).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true).get();
queryProcessor(cli).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true).get();
assertIndex(CACHE_NAME, TBL_NAME, IDX_NAME_1, field(FIELD_NAME_1));
put(cli, 0, KEY_AFTER);
assertIndexUsed(IDX_NAME_1, SQL_SIMPLE_FIELD_1, SQL_ARG_1);
assertSqlSimpleData(SQL_SIMPLE_FIELD_1, KEY_AFTER - SQL_ARG_1);
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class DynamicIndexAbstractConcurrentSelfTest method testConcurrentCacheDestroy.
/**
* Check what happen in case cache is destroyed before operation is started.
*
* @throws Exception If failed.
*/
public void testConcurrentCacheDestroy() throws Exception {
// Start complex topology.
Ignite srv1 = Ignition.start(serverConfiguration(1));
Ignition.start(serverConfiguration(2));
Ignition.start(serverConfiguration(3, true));
Ignite cli = Ignition.start(clientConfiguration(4));
// Start cache and populate it with data.
IgniteCache cache = createSqlCache(cli);
put(cli, KEY_AFTER);
// Start index operation and block it on coordinator.
blockIndexing(srv1);
QueryIndex idx = index(IDX_NAME_1, field(FIELD_NAME_1));
final IgniteInternalFuture<?> idxFut = queryProcessor(srv1).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, false);
Thread.sleep(100);
// Destroy cache (drop table).
destroySqlCache(cli);
// Unblock indexing and see what happens.
unblockIndexing(srv1);
try {
idxFut.get();
fail("Exception has not been thrown.");
} catch (SchemaOperationException e) {
// No-op.
}
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class GridQueryProcessor method onSchemaProposeDiscovery.
/**
* Process schema propose message from discovery thread.
*
* @param msg Message.
* @return {@code True} if exchange should be triggered.
*/
private boolean onSchemaProposeDiscovery(SchemaProposeDiscoveryMessage msg) {
SchemaAbstractOperation op = msg.operation();
UUID opId = op.id();
String cacheName = op.cacheName();
if (!msg.initialized()) {
// Ensure cache exists on coordinator node.
DynamicCacheDescriptor cacheDesc = ctx.cache().cacheDescriptor(cacheName);
if (cacheDesc == null) {
if (log.isDebugEnabled())
log.debug("Received schema propose discovery message, but cache doesn't exist " + "(will report error) [opId=" + opId + ", msg=" + msg + ']');
msg.onError(new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, cacheName));
} else {
CacheConfiguration ccfg = cacheDesc.cacheConfiguration();
if (ccfg.getCacheMode() == CacheMode.LOCAL) {
// Distributed operation is not allowed on LOCAL caches.
if (log.isDebugEnabled())
log.debug("Received schema propose discovery message, but cache is LOCAL " + "(will report error) [opId=" + opId + ", msg=" + msg + ']');
msg.onError(new SchemaOperationException("Schema changes are not supported for LOCAL cache."));
} else {
// Preserve deployment ID so that we can distinguish between different caches with the same name.
if (msg.deploymentId() == null)
msg.deploymentId(cacheDesc.deploymentId());
assert F.eq(cacheDesc.deploymentId(), msg.deploymentId());
}
}
}
// Complete client future and exit immediately in case of error.
if (msg.hasError()) {
SchemaOperationClientFuture cliFut = schemaCliFuts.remove(opId);
if (cliFut != null)
cliFut.onDone(msg.error());
return false;
}
return onSchemaProposeDiscovery0(msg);
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class GridQueryProcessor method startIndexOperationDistributed.
/**
* Start distributed index change operation.
*
* @param op Operation.
* @return Future.
*/
private IgniteInternalFuture<?> startIndexOperationDistributed(SchemaAbstractOperation op) {
SchemaOperationClientFuture fut = new SchemaOperationClientFuture(op.id());
SchemaOperationClientFuture oldFut = schemaCliFuts.put(op.id(), fut);
assert oldFut == null;
try {
ctx.discovery().sendCustomEvent(new SchemaProposeDiscoveryMessage(op));
if (log.isDebugEnabled())
log.debug("Sent schema propose discovery message [opId=" + op.id() + ", op=" + op + ']');
boolean disconnected0;
synchronized (stateMux) {
disconnected0 = disconnected;
}
if (disconnected0) {
fut.onDone(new SchemaOperationException("Client node is disconnected (operation result is unknown)."));
schemaCliFuts.remove(op.id());
}
} catch (Exception e) {
if (e instanceof SchemaOperationException)
fut.onDone(e);
else {
fut.onDone(new SchemaOperationException("Failed to start schema change operation due to " + "unexpected exception [opId=" + op.id() + ", op=" + op + ']', e));
}
schemaCliFuts.remove(op.id());
}
return fut;
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class GridQueryProcessor method processIndexOperationLocal.
/**
* Process index operation.
*
* @param op Operation.
* @param type Type descriptor.
* @param depId Cache deployment ID.
* @param cancelTok Cancel token.
* @throws SchemaOperationException If failed.
*/
public void processIndexOperationLocal(SchemaAbstractOperation op, QueryTypeDescriptorImpl type, IgniteUuid depId, SchemaIndexOperationCancellationToken cancelTok) throws SchemaOperationException {
if (log.isDebugEnabled())
log.debug("Started local index operation [opId=" + op.id() + ']');
String cacheName = op.cacheName();
GridCacheAdapter cache = ctx.cache().internalCache(cacheName);
if (cache == null || !F.eq(depId, cache.context().dynamicDeploymentId()))
throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, cacheName);
try {
if (op instanceof SchemaIndexCreateOperation) {
SchemaIndexCreateOperation op0 = (SchemaIndexCreateOperation) op;
QueryIndexDescriptorImpl idxDesc = QueryUtils.createIndexDescriptor(type, op0.index());
SchemaIndexCacheVisitor visitor = new SchemaIndexCacheVisitorImpl(this, cache.context(), cacheName, op0.tableName(), cancelTok);
idx.dynamicIndexCreate(op0.schemaName(), op0.tableName(), idxDesc, op0.ifNotExists(), visitor);
} else if (op instanceof SchemaIndexDropOperation) {
SchemaIndexDropOperation op0 = (SchemaIndexDropOperation) op;
idx.dynamicIndexDrop(op0.schemaName(), op0.indexName(), op0.ifExists());
} else
throw new SchemaOperationException("Unsupported operation: " + op);
} catch (Exception e) {
if (e instanceof SchemaOperationException)
throw (SchemaOperationException) e;
else
throw new SchemaOperationException("Schema change operation failed: " + e.getMessage(), e);
}
}
Aggregations