proto/cluster.proto (119 lines of code) (raw):
syntax = "proto3";
package gitaly;
import "lint.proto";
import "raftpb/raft.proto"; // Upstream go.etcd.io/raft/v3/raftpb/raft.proto
option go_package = "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb";
// RaftEntry encapsulates critical data for replication using etcd/raft library.
// It has a request ID allowing the primary to track when the action is
// effectively applied.
message RaftEntry {
// LogData contains serialized log data, including the log entry itself
// and all attached files in the log entry's directory. These data are
// exchanged at the Transport layer before sending and after receiving
// messages. They remain transparent to the core Raft engine.
message LogData {
// local_path is the path to the staging log entry directory. Before the
// request is sent to other nodes, this whole directory of the entry is
// serialized. So, this field is only relevant to the primary node who
// issues the request.
bytes local_path = 1;
// packed is the serialized form of the log entry data. Transport
// implementations populates this field before sending out messages to other
// members of a Raft group.
bytes packed = 2;
}
// id is the unique identifier for the Raft message. This ID is generated by
// an in-memory event registry. Raft uses this ID to track the commit status
// of a log entry.
uint64 id = 1;
// data represents packed and serialized log data.
LogData data = 2;
}
// PartitionKey identifies which partition this replica belongs to.
message PartitionKey {
// authority_name represents the storage that created the partition.
string authority_name = 1 [(gitaly.storage) = true];
// partition_id is the local incrementing ID of a specific partition within a
// storage. Together with `authority_name`, this forms a unique identifier for
// a partition across the cluster. A partition belongs to a Raft group.
uint64 partition_id = 2;
}
// ReplicaID uniquely identifies a replica in the Raft cluster.
// It combines partition information with node-specific details.
message ReplicaID {
// partition_key identifies which partition this replica belongs to.
PartitionKey partition_key = 1;
// member_id is the unique identifier assigned by etcd/raft.
uint64 member_id = 2;
// storage_name is the name of the storage where this replica is hosted.
string storage_name = 3;
// Metadata contains routing information for the replica.
message Metadata {
// address is the network address of the replica.
string address = 1;
}
// metadata contains replica information.
Metadata metadata = 4;
// ReplicaType indicates whether a replica is a voter or learner in the Raft cluster
enum ReplicaType {
// REPLICA_TYPE_UNSPECIFIED.
REPLICA_TYPE_UNSPECIFIED = 0;
// REPLICA_TYPE_VOTER indicates a replica that can participate in Raft elections and voting.
REPLICA_TYPE_VOTER = 1;
// REPLICA_TYPE_LEARNER indicates a replica that receives updates but cannot vote.
REPLICA_TYPE_LEARNER = 2;
}
// type indicates whether the replica is learner or voter.
ReplicaType type = 5;
}
// RaftMessageRequest is a request for the SendMessage RPC. It serves as a
// wrapper for raftpb.Message. etcd/raft's state machines on each member emit
// this message. Since Gitaly employs multi-raft, routing metadata is attached
// to ensure the message reaches the correct Raft group inside the receiving
// Gitaly server.
message RaftMessageRequest {
// cluster_id is the identifier of the Raft cluster to which this message belongs.
string cluster_id = 1;
// replica_id uniquely identifies a replica in the Raft cluster.
ReplicaID replica_id = 2;
// message is the Raft message to be delivered.
raftpb.Message message = 3;
}
// RaftMessageResponse represents a response to the SendMessage RPC.
message RaftMessageResponse {
}
// RaftSnapshotMessageRequest is the input to SendSnapshot RPC.
message RaftSnapshotMessageRequest {
oneof raft_snapshot_payload {
// raft_msg is a wrapper for raftpb.Message
RaftMessageRequest raft_msg = 1;
// chunk of snapshot data
bytes chunk = 2;
}
}
// RaftSnapshotMessageResponse is the response to SendSnapshot RPC.
message RaftSnapshotMessageResponse {
// destination is where the snapshot is saved.
string destination = 1;
// snapshot_size is the snapshot size in bytes.
uint64 snapshot_size = 2;
}
// RaftService manages the sending of Raft messages to peers.
service RaftService {
// SendMessage processes Raft messages and ensures they are handled by
// the receiving node to update its Raft state machine.
rpc SendMessage(stream RaftMessageRequest) returns (RaftMessageResponse) {
option (op_type) = {
op: MUTATOR
scope_level: STORAGE
};
}
// SendSnapshot sends raft snapshots from the leader to the follower node. Typically it
// would be useful for nodes to catch up to the latest state.
rpc SendSnapshot(stream RaftSnapshotMessageRequest) returns (RaftSnapshotMessageResponse) {
option (op_type) = {
op: MUTATOR
scope_level: STORAGE
};
}
}