Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ public ConfigPhysicalPlanType getType() {
return this.type;
}

/**
* Serializes this plan, including its type discriminator and implementation-specific payload.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contract is not true for every implementation. ConfigPhysicalReadPlan.serializeImpl() is deliberately a no-op, so serializeToByteBuffer() returns an empty buffer with neither a type discriminator nor a payload for read plans. Please qualify the Javadoc to say that it serializes whatever the concrete implementation emits, or explicitly document the read-plan exception.

*
* @return a buffer positioned at the beginning of the serialized plan
*/
@Override
public ByteBuffer serializeToByteBuffer() {
try (final PublicBAOS byteArrayOutputStream = new PublicBAOS();
Expand All @@ -189,6 +194,13 @@ public int getSerializedSize() throws IOException {

public static class Factory {

/**
* Deserializes a plan from the buffer using the encoded type discriminator.
*
* @param buffer the buffer containing one serialized plan
* @return the deserialized plan
* @throws IOException if the encoded plan type or payload cannot be read

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A truncated buffer is not covered by this documented exception: buffer.getShort() throws the unchecked BufferUnderflowException when fewer than two bytes remain. Please either validate/wrap buffer underflow as IOException or document the unchecked failure instead of promising IOException whenever the encoded type or payload cannot be read.

*/
public static ConfigPhysicalPlan create(final ByteBuffer buffer) throws IOException {
final short planType = buffer.getShort();
final ConfigPhysicalPlanType configPhysicalPlanType =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,13 @@ public R process(final ConfigPhysicalPlan plan, final C context) {
}
}

/** Top Level Description */
/**
* Dispatches ConfigPhysicalPlan instances to type-specific visitor methods.
*
* <p>When a new plan type is introduced, the top-level dispatch and the corresponding visitor
* method must be updated together. Default visitor methods should document whether they delegate
* to the top-level handler, return a default value, or reject the plan.
*/
public abstract R visitPlan(final ConfigPhysicalPlan plan, final C context);

public R visitCreateDatabase(final DatabaseSchemaPlan createDatabasePlan, final C context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ public String getClusterId() {
return clusterInfo.getClusterId();
}

/**
* Waits up to the specified time for the cluster ID to become available.
*
* @param maxWaitTime maximum wait time in milliseconds
* @return the cluster ID, or null if it is unavailable after the timeout or the wait is
* interrupted
*/
public String getClusterIdWithRetry(long maxWaitTime) {
long startTime = System.currentTimeMillis();
while (clusterInfo.getClusterId() == null
Expand All @@ -109,7 +116,12 @@ private void generateClusterId() {
}
}

// TODO: Parallel test ConfigNode and DataNode
/**
* Tests connectivity from this ConfigNode to all registered ConfigNodes and DataNodes and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The probes do not all originate from this ConfigNode. This method sends the complete node list to every registered ConfigNode and DataNode, each recipient performs doConnectionTest(nodeLocations), and the leader aggregates those per-node results. Please describe this as a cluster-wide or all-to-all connectivity test coordinated by this ConfigNode.

* aggregates the results.
*
* @return aggregated connection-test results
*/
public TTestConnectionResp submitTestConnectionTaskToEveryNode() {
TTestConnectionResp resp = new TTestConnectionResp();
resp.resultList = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,18 @@
import static org.apache.iotdb.commons.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
import static org.apache.iotdb.commons.schema.table.Audit.TREE_MODEL_AUDIT_DATABASE;

/** Entry of all management, AssignPartitionManager, AssignRegionManager. */
/**
* Coordinates ConfigNode control-plane managers and routes requests related to nodes, schema,
* partitions, procedures, load management, plugins, quotas, TTL, and subscriptions.
*/
public class ConfigManager implements IManager {

private static final Logger LOGGER = LoggerFactory.getLogger(ConfigManager.class);

private static final ConfigNodeConfig CONF = ConfigNodeDescriptor.getInstance().getConf();
private static final CommonConfig COMMON_CONF = CommonDescriptor.getInstance().getConfig();

/** Manage PartitionTable read/write requests through the ConsensusLayer. */
/** Manages replicated ConfigRegion plans and reads through the consensus layer. */
private final AtomicReference<ConsensusManager> consensusManager = new AtomicReference<>();

/** Manage cluster-level info */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
* EventService periodically check statistics and broadcast corresponding change event if necessary.
*/
/** Periodically checks cluster events that require ConfigNode-side handling. */
public class EventService {

private static final Logger LOGGER = LoggerFactory.getLogger(EventService.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
import java.util.stream.Collectors;

/**
* HeartbeatService periodically sending heartbeat requests from ConfigNode-leader to all other
* cluster Nodes.
* Periodically sends heartbeat requests from the ConfigNode leader to registered ConfigNodes,
* DataNodes, and AINodes, and updates the corresponding load information.
*/
public class HeartbeatService {

Expand Down Expand Up @@ -135,7 +135,7 @@ public void reloadHeartbeatInterval() {
}
}

/** loop body of the heartbeat thread. */
/** Executes one leader heartbeat cycle. */
private void heartbeatLoopBody() {
// The consensusManager of configManager may not be fully initialized at this time
Optional.ofNullable(getConsensusManager())
Expand Down Expand Up @@ -300,7 +300,7 @@ private void pingRegisteredDataNodes(
/**
* Send heartbeat requests to all the Registered AINodes.
*
* @param registeredAINodes DataNodes that registered in cluster
* @param registeredAINodes AINodes registered in the cluster
*/
private void pingRegisteredAINodes(
TAIHeartbeatReq heartbeatReq, List<TAINodeConfiguration> registeredAINodes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/** StatisticsService periodically update load statistics for all load cache. */
/** Periodically aggregates heartbeat samples into cluster load statistics. */
public class StatisticsService {

private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsService.class);
Expand All @@ -44,7 +44,7 @@ public StatisticsService(LoadCache loadCache) {
this.loadCache = loadCache;
}

/** Load statistics executor service. */
/** Guards load-statistics scheduling across lifecycle and leadership transitions. */
private final Object statisticsScheduleMonitor = new Object();

private Future<?> currentLoadStatisticsFuture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,8 @@ public TAINodeConfiguration getRegisteredAINode(int aiNodeId) {
}

/**
* Register AINode. Use synchronized to make sure
* Serialize AINode registration so concurrent requests cannot violate the single-AINode
* registration constraint.
*
* @param req TAINodeRegisterReq
* @return AINodeConfigurationDataSet. The {@link TSStatus} will be set to {@link
Expand All @@ -541,15 +542,15 @@ public synchronized DataSet registerAINode(TAINodeRegisterReq req) {
int aiNodeId = nodeInfo.generateNextNodeId();
getLoadManager().getLoadCache().createNodeHeartbeatCache(NodeType.AINode, aiNodeId);
RegisterAINodePlan registerAINodePlan = new RegisterAINodePlan(req.getAiNodeConfiguration());
// Register new DataNode
// Register new AINode
registerAINodePlan.getAINodeConfiguration().getLocation().setAiNodeId(aiNodeId);
try {
getConsensusManager().write(registerAINodePlan);
} catch (ConsensusException e) {
LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
}

// update datanode's versionInfo
// update AINode's versionInfo
UpdateVersionInfoPlan updateVersionInfoPlan =
new UpdateVersionInfoPlan(req.getVersionInfo(), aiNodeId);
try {
Expand Down Expand Up @@ -655,7 +656,7 @@ public DataNodeConfigurationResp getDataNodeConfiguration(GetDataNodeConfigurati
}

/**
* Only leader use this interface.
* Called only on the ConfigNode leader.
*
* @return The number of registered Nodes
*/
Expand All @@ -664,7 +665,7 @@ public int getRegisteredNodeCount() {
}

/**
* Only leader use this interface.
* Called only on the ConfigNode leader.
*
* @return The number of registered DataNodes
*/
Expand All @@ -673,7 +674,7 @@ public int getRegisteredDataNodeCount() {
}

/**
* Only leader use this interface.
* Called only on the ConfigNode leader.
*
* @return All registered DataNodes
*/
Expand All @@ -682,7 +683,7 @@ public List<TDataNodeConfiguration> getRegisteredDataNodes() {
}

/**
* Only leader use this interface.
* Called only on the ConfigNode leader.
*
* <p>Notice: The result will be an empty TDataNodeConfiguration if the specified DataNode doesn't
* register
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ public class PartitionManager {
// Monitor for leadership change
private final Object scheduleMonitor = new Object();

/** Region cleaner. */
// Try to delete Regions in every 10s
/** Period, in seconds, at which the region maintainer performs maintenance and cleanup. */
private static final int REGION_MAINTAINER_WORK_INTERVAL = 10;

private final ScheduledExecutorService regionMaintainer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@
import static org.apache.iotdb.commons.schema.SchemaConstant.ROOT;
import static org.apache.iotdb.commons.schema.SchemaConstant.TABLE_MNODE_TYPE;

// Since the ConfigMTree is all stored in memory, thus it is not restricted to manage MNode through
// MTreeStore.
// ConfigMTree stores nodes in memory. ConfigMTreeStore provides in-memory node access and traversal
// helpers.
public class ConfigMTree {

private static final String TABLE_ERROR_MSG =
Expand Down Expand Up @@ -136,7 +136,7 @@ public void clear() {
// region database Management

/**
* CREATE DATABASE. Make sure check seriesPath before setting database
* Create the database after validating the path; intermediate nodes are created when necessary.
*
* @param path path
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public final boolean hasLock() {
* The code to undo what was done by the execute() code. It is called when the procedure or one of
* the sub-procedures failed or an abort was requested. It should cleanup all the resources
* created by the execute() call. The implementation must be idempotent since rollback() may be
* called multiple time in case of machine failure in the middle of the execution.
* called multiple times in case of machine failure in the middle of the execution.
*
* @param env the environment passed to the ProcedureExecutor
* @throws IOException temporary failure, the rollback will retry later
Expand Down Expand Up @@ -277,7 +277,7 @@ final void releaseExecution() {
}

/**
* Internal method called by the ProcedureExecutor that starts the user-level code execute().
* Internal method called by the ProcedureExecutor that invokes the user-level execute().
*
* @param env execute environment
* @return sub procedures
Expand All @@ -292,7 +292,7 @@ protected Procedure<Env>[] doExecute(Env env) throws InterruptedException {
}

/**
* Internal method called by the ProcedureExecutor that starts the user-level code rollback().
* Internal method called by the ProcedureExecutor that invokes the user-level rollback().
*
* @param env execute environment
* @throws IOException ioe
Expand Down Expand Up @@ -336,7 +336,7 @@ public final ProcedureLockState doAcquireLock(Env env, IProcedureStore store) {
}

/**
* Presist lock state of the procedure
* Persist the procedure's lock state.
*
* @param env environment
* @param store ProcedureStore
Expand Down Expand Up @@ -616,7 +616,7 @@ public boolean isLockedWhenLoading() {
// Runtime state, updated every operation by the ProcedureExecutor
//
// There is always 1 thread at the time operating on the state of the procedure.
// The ProcedureExecutor may check and set states, or some Procecedure may
// The ProcedureExecutor may check and set states, or some Procedure may
// update its own state. but no concurrent updates. we use synchronized here
// just because the procedure can get scheduled on different executor threads on each step.
// ==============================================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,17 @@ protected void remove(Set<Integer> nodeIds) throws IoTDBException {
ConfigNodeMessages.THE_REMOVE_CONFIGNODE_SCRIPT_HAS_BEEN_DEPRECATED_PLEASE_CONNECT_TO, -1);
}

/**
* Starts the ConfigNode services in dependency order.
*
* <p>The method must preserve the distinction between seed and non-seed ConfigNodes and must
* start the RPC service only after the local services required to handle requests are ready.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true for the initial non-seed path. That path intentionally calls setUpRPCService() before sendRegisterConfigNodeRequest() and before the node has joined a consensus group so that the leader can schedule expansion. Please document this exception instead of stating that RPC always starts only after the required local services are ready.

*/
public void active() {
LOGGER.info(ConfigNodeMessages.ACTIVATING, ConfigNodeConstant.GLOBAL_NAME);

try {
// Process pid file, register deleteOnExit
processPid();
// Add shutdown hook
addShutDownHook();
Expand Down Expand Up @@ -503,6 +510,12 @@ public void deactivate() throws IOException {
LOGGER.info(ConfigNodeMessages.IS_DEACTIVATED, ConfigNodeConstant.GLOBAL_NAME);
}

/**
* Stops ConfigNode services and releases their resources in reverse dependency order.
*
* <p>The operation should be safe to invoke during partial startup and should not leave
* background scheduling, RPC, or consensus resources running.
Comment on lines +514 to +517

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cleanup contract is stronger than the implementation. deactivate() deregisters services and ConfigManager.close() shuts down the region maintainer, procedure executor, and consensus, but consensus shutdown does not guarantee that ConfigRegionStateMachine.stopLeaderServices() runs; ConfigRegionStateMachine.stop() itself only notifies the pipe runtime. The shutdown is also not implemented as reverse dependency order. Please narrow this Javadoc to the actual best-effort deactivation followed by process exit, or implement the promised cleanup.

*/
public void stop() {
try {
deactivate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
import java.util.List;
import java.util.function.Supplier;

/**
* Applies replicated write and query fragment operations to one DataRegion and exposes its snapshot
* and region-resource lifecycle to the consensus layer.
*
* <p>Write-process rejection is retried here to preserve the atomicity expected by the consensus
* apply path; other statuses are delegated to the consensus retry mechanism.
*/
public class DataRegionStateMachine extends BaseStateMachine {

private static final Logger logger = LoggerFactory.getLogger(DataRegionStateMachine.class);
Expand All @@ -74,7 +81,8 @@ public DataRegionStateMachine(DataRegion region) {

@Override
public void start() {
// do nothing
// The consensus implementation owns the start lifecycle; this state machine has no additional
// start action.
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
import java.util.List;
import java.util.Objects;

/**
* Applies replicated schema operations to one SchemaRegion and coordinates schema-region snapshot,
* Pipe-leader, and attribute-security lifecycle callbacks.
*/
public class SchemaRegionStateMachine extends BaseStateMachine {

private static final Logger logger = LoggerFactory.getLogger(SchemaRegionStateMachine.class);
Expand All @@ -60,7 +64,8 @@ public SchemaRegionStateMachine(final ISchemaRegion schemaRegion) {

@Override
public void start() {
// Do nothing
// The consensus implementation owns the start lifecycle; this state machine has no additional
// start action.
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@
import static org.apache.iotdb.rpc.RpcUtils.TIME_PRECISION;
import static org.apache.iotdb.rpc.TSStatusCode.QUERY_WAS_KILLED;

/**
* Implements the client-facing RPC surface for sessions, SQL execution, writes, query results,
* metadata operations, authentication, and resource control.
*
* <p>This class adapts protocol requests to the Coordinator and DataNode managers; it must preserve
* session ownership, query cleanup, authorization, timeout, and status-conversion semantics.
*/
public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(ClientRPCServiceImpl.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,13 @@
import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onIoTDBException;
import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onQueryException;

/**
* Implements the internal DataNode RPC surface used for fragment execution, region lifecycle,
* schema/data operations, load, consensus-related coordination, and cluster maintenance.
*
* <p>Internal requests may arrive during startup, shutdown, migration, or recovery, so methods must
* document their readiness checks and idempotency behavior where it is not obvious.
*/
public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface {
private static final Logger LOGGER =
LoggerFactory.getLogger(DataNodeInternalRPCServiceImpl.class);
Expand Down
Loading