use of org.apache.ignite.lang.NodeStoppingException in project ignite-3 by apache.
the class TableManager method start.
/**
* {@inheritDoc}
*/
@Override
public void start() {
tablesCfg.tables().listenElements(new ConfigurationNamedListListener<>() {
@Override
public CompletableFuture<?> onCreate(ConfigurationNotificationEvent<TableView> ctx) {
if (!busyLock.enterBusy()) {
String tblName = ctx.newValue().name();
UUID tblId = ((ExtendedTableView) ctx.newValue()).id();
fireEvent(TableEvent.CREATE, new TableEventParameters(ctx.storageRevision(), tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
onTableCreateInternal(ctx);
} finally {
busyLock.leaveBusy();
}
return CompletableFuture.completedFuture(null);
}
/**
* Method for handle a table configuration event.
*
* @param ctx Configuration event.
*/
private void onTableCreateInternal(ConfigurationNotificationEvent<TableView> ctx) {
String tblName = ctx.newValue().name();
UUID tblId = ((ExtendedTableView) ctx.newValue()).id();
// configuration, which is not supported now.
assert ((ExtendedTableView) ctx.newValue()).assignments() != null : IgniteStringFormatter.format("Table [id={}, name={}] has empty assignments.", tblId, tblName);
// TODO: IGNITE-16369 Listener with any placeholder should be used instead.
((ExtendedTableConfiguration) tablesCfg.tables().get(tblName)).schemas().listenElements(new ConfigurationNamedListListener<>() {
@Override
public CompletableFuture<?> onCreate(ConfigurationNotificationEvent<SchemaView> schemasCtx) {
long causalityToken = schemasCtx.storageRevision();
if (!busyLock.enterBusy()) {
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
// FIXME: https://issues.apache.org/jira/browse/IGNITE-16369
if (ctx.storageRevision() != schemasCtx.storageRevision()) {
return tablesByIdVv.get(causalityToken).thenAccept(tablesById -> {
TableImpl table = tablesById.get(tblId);
((SchemaRegistryImpl) table.schemaView()).onSchemaRegistered(SchemaSerializerImpl.INSTANCE.deserialize((schemasCtx.newValue().schema())));
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, table), null);
});
}
return CompletableFuture.completedFuture(null);
} catch (Exception e) {
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, tblId, tblName), e);
return CompletableFuture.failedFuture(e);
} finally {
busyLock.leaveBusy();
}
}
});
((ExtendedTableConfiguration) tablesCfg.tables().get(tblName)).assignments().listen(assignmentsCtx -> {
if (!busyLock.enterBusy()) {
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
// FIXME: https://issues.apache.org/jira/browse/IGNITE-16369
if (ctx.storageRevision() == assignmentsCtx.storageRevision()) {
return CompletableFuture.completedFuture(null);
} else {
return updateAssignmentInternal(assignmentsCtx.storageRevision(), tblId, assignmentsCtx);
}
} finally {
busyLock.leaveBusy();
}
});
createTableLocally(ctx.storageRevision(), tblName, tblId, (List<List<ClusterNode>>) ByteUtils.fromBytes(((ExtendedTableView) ctx.newValue()).assignments()), SchemaSerializerImpl.INSTANCE.deserialize(((ExtendedTableView) ctx.newValue()).schemas().get(String.valueOf(INITIAL_SCHEMA_VERSION)).schema()));
}
private CompletableFuture<?> updateAssignmentInternal(long causalityToken, UUID tblId, ConfigurationNotificationEvent<byte[]> assignmentsCtx) {
List<List<ClusterNode>> oldAssignments = (List<List<ClusterNode>>) ByteUtils.fromBytes(assignmentsCtx.oldValue());
List<List<ClusterNode>> newAssignments = (List<List<ClusterNode>>) ByteUtils.fromBytes(assignmentsCtx.newValue());
CompletableFuture<?>[] futures = new CompletableFuture<?>[oldAssignments.size()];
// TODO: be exact same amount of partitions and replicas for both old and new assignments
for (int i = 0; i < oldAssignments.size(); i++) {
int partId = i;
List<ClusterNode> oldPartitionAssignment = oldAssignments.get(partId);
List<ClusterNode> newPartitionAssignment = newAssignments.get(partId);
var toAdd = new HashSet<>(newPartitionAssignment);
toAdd.removeAll(oldPartitionAssignment);
// Create new raft nodes according to new assignments.
futures[i] = tablesByIdVv.get(causalityToken).thenCompose(tablesById -> {
InternalTable internalTable = tablesById.get(tblId).internalTable();
try {
return raftMgr.updateRaftGroup(raftGroupName(tblId, partId), newPartitionAssignment, toAdd, () -> new PartitionListener(tblId, new VersionedRowStore(internalTable.storage().getOrCreatePartition(partId), txManager))).thenAccept(updatedRaftGroupService -> ((InternalTableImpl) internalTable).updateInternalTableRaftGroupService(partId, updatedRaftGroupService)).exceptionally(th -> {
LOG.error("Failed to update raft groups one the node", th);
return null;
});
} catch (NodeStoppingException e) {
throw new AssertionError("Loza was stopped before Table manager", e);
}
});
}
return CompletableFuture.allOf(futures);
}
@Override
public CompletableFuture<?> onRename(String oldName, String newName, ConfigurationNotificationEvent<TableView> ctx) {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<?> onDelete(ConfigurationNotificationEvent<TableView> ctx) {
if (!busyLock.enterBusy()) {
String tblName = ctx.oldValue().name();
UUID tblId = ((ExtendedTableView) ctx.oldValue()).id();
fireEvent(TableEvent.DROP, new TableEventParameters(ctx.storageRevision(), tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
dropTableLocally(ctx.storageRevision(), ctx.oldValue().name(), ((ExtendedTableView) ctx.oldValue()).id(), (List<List<ClusterNode>>) ByteUtils.fromBytes(((ExtendedTableView) ctx.oldValue()).assignments()));
} finally {
busyLock.leaveBusy();
}
return CompletableFuture.completedFuture(null);
}
});
engine.start();
DataRegion defaultDataRegion = engine.createDataRegion(dataStorageCfg.defaultRegion());
dataRegions.put(DEFAULT_DATA_REGION_NAME, defaultDataRegion);
defaultDataRegion.start();
}
use of org.apache.ignite.lang.NodeStoppingException in project ignite-3 by apache.
the class TableManagerTest method testGetTableDuringCreation.
/**
* Instantiates a table and prepares Table manager.
*/
@Test
public void testGetTableDuringCreation() {
TableDefinition scmTbl = SchemaBuilders.tableBuilder("PUBLIC", DYNAMIC_TABLE_FOR_DROP_NAME).columns(SchemaBuilders.column("key", ColumnType.INT64).build(), SchemaBuilders.column("val", ColumnType.INT64).asNullable(true).build()).withPrimaryKey("key").build();
Phaser phaser = new Phaser(2);
CompletableFuture<Table> createFut = CompletableFuture.supplyAsync(() -> {
try {
return mockManagersAndCreateTableWithDelay(scmTbl, tblManagerFut, phaser);
} catch (NodeStoppingException e) {
fail(e.getMessage());
}
return null;
});
CompletableFuture<Table> getFut = CompletableFuture.supplyAsync(() -> {
phaser.awaitAdvance(0);
return tblManagerFut.join().table(scmTbl.canonicalName());
});
CompletableFuture<Collection<Table>> getAllTablesFut = CompletableFuture.supplyAsync(() -> {
phaser.awaitAdvance(0);
return tblManagerFut.join().tables();
});
assertFalse(createFut.isDone());
assertFalse(getFut.isDone());
assertFalse(getAllTablesFut.isDone());
phaser.arrive();
assertSame(createFut.join(), getFut.join());
assertEquals(1, getAllTablesFut.join().size());
}
use of org.apache.ignite.lang.NodeStoppingException in project ignite-3 by apache.
the class DefaultMessagingService method send0.
/**
* Sends a message. If the target is the current node, then message will be delivered immediately.
*
* @param recipient Target cluster node. TODO: Maybe {@code null} due to IGNITE-16373.
* @param address Target address.
* @param msg Message.
* @param correlationId Correlation id. Not null iff the message is a response to a {@link #invoke} request.
* @return Future of the send operation.
*/
private CompletableFuture<Void> send0(@Nullable ClusterNode recipient, NetworkAddress address, NetworkMessage msg, @Nullable Long correlationId) {
if (connectionManager.isStopped()) {
return failedFuture(new NodeStoppingException());
}
InetSocketAddress addr = new InetSocketAddress(address.host(), address.port());
if (isSelf(recipient, address.consistentId(), addr)) {
if (correlationId != null) {
onInvokeResponse(msg, correlationId);
} else {
sendToSelf(msg, null);
}
return CompletableFuture.completedFuture(null);
}
NetworkMessage message = correlationId != null ? responseFromMessage(msg, correlationId) : msg;
String recipientConsistentId = recipient != null ? recipient.name() : address.consistentId();
return this.sendMessage0(message, recipientConsistentId, addr);
}
use of org.apache.ignite.lang.NodeStoppingException in project ignite-3 by apache.
the class DefaultMessagingService method invoke0.
/**
* Sends an invocation request. If the target is the current node, then message will be delivered immediately.
*
* @param recipient Target cluster node. TODO: Maybe {@code null} due to IGNITE-16373.
* @param addr Target address.
* @param msg Message.
* @param timeout Invocation timeout.
* @return A future holding the response or error if the expected response was not received.
*/
private CompletableFuture<NetworkMessage> invoke0(@Nullable ClusterNode recipient, NetworkAddress addr, NetworkMessage msg, long timeout) {
if (connectionManager.isStopped()) {
return failedFuture(new NodeStoppingException());
}
long correlationId = createCorrelationId();
CompletableFuture<NetworkMessage> responseFuture = new CompletableFuture<NetworkMessage>().orTimeout(timeout, TimeUnit.MILLISECONDS);
requestsMap.put(correlationId, responseFuture);
InetSocketAddress address = new InetSocketAddress(addr.host(), addr.port());
if (isSelf(recipient, addr.consistentId(), address)) {
sendToSelf(msg, correlationId);
return responseFuture;
}
InvokeRequest message = requestFromMessage(msg, correlationId);
String recipientConsistentId = recipient != null ? recipient.name() : addr.consistentId();
return sendMessage0(message, recipientConsistentId, address).thenCompose(unused -> responseFuture);
}
use of org.apache.ignite.lang.NodeStoppingException in project ignite-3 by apache.
the class MetaStorageManager method stop.
/**
* {@inheritDoc}
*/
@Override
public void stop() {
if (!stopGuard.compareAndSet(false, true)) {
return;
}
busyLock.block();
Optional<IgniteUuid> watchId;
try {
// TODO: add busy lock for init method https://issues.apache.org/jira/browse/IGNITE-15114
if (deployFut.isDone()) {
watchId = deployFut.get();
try {
if (watchId.isPresent()) {
metaStorageSvcFut.get().stopWatch(watchId.get());
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to get meta storage service.");
throw new IgniteInternalException(e);
}
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to get watch.");
throw new IgniteInternalException(e);
}
try {
if (raftGroupServiceFut != null) {
raftGroupServiceFut.get().shutdown();
raftMgr.stopRaftGroup(METASTORAGE_RAFT_GROUP_NAME);
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("Failed to get meta storage raft group service.");
throw new IgniteInternalException(e);
} catch (NodeStoppingException e) {
throw new AssertionError("Loza was stopped before Meta Storage manager", e);
}
try {
storage.close();
} catch (Exception e) {
throw new IgniteInternalException("Exception when stopping the storage", e);
}
}
Aggregations