syntax = "proto3";
package d_engine.common;
option go_package = "github.com/deventlab/d-engine/proto/common";
// Basic definitions shared across modules
message LogId {
uint64 term = 1;
uint64 index = 2;
}
// Raft log entry
message Entry {
uint64 index = 1;
uint64 term = 2;
EntryPayload payload = 3;
}
// Log entry payload
message EntryPayload {
oneof payload {
Noop noop = 1; // No operation (internal to the protocol)
bytes command = 2; // Business write operation
MembershipChange config = 3; // Cluster configuration change
}
}
// Internal operation of the protocol
message Noop {} // Empty structure
// Cluster configuration change
message MembershipChange {
oneof change {
AddNode add_node = 1;
RemoveNode remove_node = 2;
PromoteLearner promote = 3;
BatchPromote batch_promote = 4;
BatchRemove batch_remove = 5;
}
}
message AddNode {
uint32 node_id = 1;
string address = 2;
NodeStatus status = 3; // Status of the node being added (NODE_STATUS_UNSPECIFIED, NODE_STATUS_PROMOTABLE, or NODE_STATUS_READ_ONLY)
}
message RemoveNode {
uint32 node_id = 1;
}
message PromoteLearner {
uint32 node_id = 1;
NodeStatus status = 2;
}
message BatchPromote {
repeated uint32 node_ids = 1;
NodeStatus new_status = 2;
}
message BatchRemove {
repeated uint32 node_ids = 1;
}
enum NodeStatus {
// Zero value: unspecified/default state (buf lint: ENUM_ZERO_VALUE_SUFFIX)
// Nodes in this state should explicitly set their status before joining cluster
NODE_STATUS_UNSPECIFIED = 0;
// Learner states
NODE_STATUS_PROMOTABLE = 1; // Learner that CAN be promoted to voter
NODE_STATUS_READ_ONLY = 2; // Learner that will NEVER be promoted (permanent analytics node)
// Voter state
NODE_STATUS_ACTIVE = 3; // Voting member (Follower, Candidate, or Leader)
}
message SnapshotEntry {
bytes key = 1;
bytes value = 2;
}
message SnapshotMeta {
uint64 version_high = 1;
uint64 version_low = 2;
uint64 created_at_high = 3;
uint64 created_at_low = 4;
uint32 author_id = 5;
LogId last_included = 6;
}
message Snapshot {
SnapshotMeta meta = 1;
repeated SnapshotEntry data = 2;
}
enum NodeRole {
NODE_ROLE_UNSPECIFIED = 0;
NODE_ROLE_FOLLOWER = 1;
NODE_ROLE_CANDIDATE = 2;
NODE_ROLE_LEADER = 3;
NODE_ROLE_LEARNER = 4;
}
// Leader election information
// Used at: Application layer (internal Raft protocol notifications)
// Purpose: Notify applications about leader changes via watch channel
// Fields: Minimal - only what Raft protocol needs
message LeaderInfo {
uint32 leader_id = 1; // Current leader node ID
uint64 term = 2; // Current Raft term
}
// Leader hint for client redirection
// Used at: Network layer (gRPC error responses)
// Purpose: Help clients redirect requests to the current leader
// Fields: Includes network address for immediate retry
message LeaderHint {
uint32 leader_id = 1; // Current leader node ID
string address = 2; // Leader's network address (e.g., "127.0.0.1:5001")
}