feat(cluster): implement distributed clustering with etcd coordination

- Integrate etcd-client for distributed coordination and leader election
- Add remote client macros with proper formatting for all services
- Implement RequestMetrics for tracking RPC performance and errors
- Add rate limiting mechanism across all service endpoints
- Create ElectionRequest and ElectionResult message types for leader election
- Add role management with primary/replica switching capabilities
- Implement health checker with automatic failover detection
- Add repository count metrics for cluster monitoring
- Update Cargo.toml with etcd-client and dashmap dependencies
- Modify RepoEntry to include read_only flag for replica handling
- Implement should_accept_election logic to prevent duplicate elections
- Add RoleChangedEvent handling for cluster role updates
This commit is contained in:
zhenyi
2026-06-08 14:31:29 +08:00
parent d243dce027
commit 8f472a0443
37 changed files with 4691 additions and 83 deletions
+122
View File
@@ -139,6 +139,113 @@ message RepositoryMaintenanceResponse {
string stderr = 3;
}
// ── Hooks Management ──────────────────────────────────────────────────
message ListHooksRequest {
RepositoryHeader repository = 1;
}
message HookInfo {
string hook_type = 1;
string level = 2; // "server" or "custom"
string path = 3;
}
message ListHooksResponse {
repeated HookInfo hooks = 1;
}
message SetCustomHookRequest {
RepositoryHeader repository = 1;
string hook_name = 2; // "pre-receive", "update", "post-receive"
string content = 3; // Hook script content
}
message RemoveCustomHookRequest {
RepositoryHeader repository = 1;
string hook_name = 2;
}
// ── Snapshot ──────────────────────────────────────────────────────────
enum SnapshotStorage {
SNAPSHOT_STORAGE_LOCAL = 0;
SNAPSHOT_STORAGE_S3 = 1;
SNAPSHOT_STORAGE_GCS = 2;
}
message SnapshotInfo {
string snapshot_id = 1;
string relative_path = 2;
uint64 size_bytes = 3;
string created_at = 4; // ISO 8601
string head_oid = 5;
}
message CreateSnapshotRequest {
RepositoryHeader repository = 1;
SnapshotStorage storage = 2;
string storage_path = 3;
}
message CreateSnapshotResponse {
string snapshot_id = 1;
uint64 size_bytes = 2;
string head_oid = 3;
}
message RestoreSnapshotRequest {
RepositoryHeader target_repository = 1;
string snapshot_id = 2;
SnapshotStorage storage = 3;
string storage_path = 4;
}
message ListSnapshotsRequest {
RepositoryHeader repository = 1;
uint32 limit = 2;
}
message ListSnapshotsResponse {
repeated SnapshotInfo snapshots = 1;
}
message DeleteSnapshotRequest {
string snapshot_id = 1;
SnapshotStorage storage = 2;
}
// ── Repository Move ──────────────────────────────────────────────────
enum MoveRepositoryState {
MOVE_STATE_UNKNOWN = 0;
MOVE_STATE_PREPARING = 1;
MOVE_STATE_TRANSFERRING = 2;
MOVE_STATE_VERIFYING = 3;
MOVE_STATE_COMPLETED = 4;
MOVE_STATE_FAILED = 5;
MOVE_STATE_CANCELLED = 6;
}
message MoveRepositoryRequest {
RepositoryHeader source_repository = 1;
RepositoryHeader target_repository = 2;
}
message MoveRepositoryResponse {
MoveRepositoryState state = 1;
string error_message = 2;
}
message FetchRepositoryDataRequest {
RepositoryHeader repository = 1;
}
message FetchRepositoryDataResponse {
bytes data = 1;
bool done = 2;
}
service RepositoryService {
rpc GetRepository(GetRepositoryRequest) returns (Repository);
rpc InitRepository(InitRepositoryRequest) returns (Repository);
@@ -154,4 +261,19 @@ service RepositoryService {
rpc GarbageCollect(GarbageCollectRequest) returns (RepositoryMaintenanceResponse);
rpc Repack(RepackRequest) returns (RepositoryMaintenanceResponse);
rpc WriteCommitGraph(WriteCommitGraphRequest) returns (RepositoryMaintenanceResponse);
// Hooks management
rpc ListHooks(ListHooksRequest) returns (ListHooksResponse);
rpc SetCustomHook(SetCustomHookRequest) returns (google.protobuf.Empty);
rpc RemoveCustomHook(RemoveCustomHookRequest) returns (google.protobuf.Empty);
// Snapshot operations
rpc CreateSnapshot(CreateSnapshotRequest) returns (CreateSnapshotResponse);
rpc RestoreSnapshot(RestoreSnapshotRequest) returns (google.protobuf.Empty);
rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse);
rpc DeleteSnapshot(DeleteSnapshotRequest) returns (google.protobuf.Empty);
// Repository move
rpc MoveRepository(MoveRepositoryRequest) returns (MoveRepositoryResponse);
rpc FetchRepositoryData(FetchRepositoryDataRequest) returns (stream FetchRepositoryDataResponse);
}