refactor(actor): implement Raft consensus algorithm for cluster leader election

- Add voting mechanism with term tracking and vote persistence
- Implement election triggering logic with majority vote counting
- Add primary/replica role transition handling with state management
- Integrate health check failure detection for automatic elections
- Refactor actor messaging system for distributed coordination
- Update repository registration to query cluster for existing primary
- Add broadcast mechanism for role change notifications
- Implement proper term comparison and duplicate request filtering
- Upgrade dependency versions including tokio-util for async utilities
- Optimize code formatting and line wrapping for improved readability
- Remove redundant blank lines and improve code structure consistency
- Enhance error logging and trace information for debugging purposes
This commit is contained in:
zhenyi
2026-06-10 12:35:10 +08:00
parent ab32e8826e
commit 9a0c26e5f6
40 changed files with 1184 additions and 449 deletions
+11 -19
View File
@@ -15,7 +15,6 @@ use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, OnceLock};
use std::time::{Duration, Instant};
struct MetricsInner {
/// Counter: total requests by (method, status_code)
/// Key: "method:status"
@@ -61,7 +60,6 @@ fn metrics() -> &'static Arc<MetricsInner> {
})
}
#[rustfmt::skip]
const DURATION_BUCKET_MS: &[u64] = &[
5, 10, 25, 50, 100, 250, 500, 1_000,
@@ -105,9 +103,7 @@ pub fn dec_active_requests() {
/// Set the repository count.
pub fn set_repository_count(count: u64) {
metrics()
.repository_count
.store(count, Ordering::Relaxed);
metrics().repository_count.store(count, Ordering::Relaxed);
}
/// Record a cache hit.
@@ -117,9 +113,7 @@ pub fn inc_cache_hits(count: u64) {
/// Record a cache miss.
pub fn inc_cache_misses(count: u64) {
metrics()
.cache_misses
.fetch_add(count, Ordering::Relaxed);
metrics().cache_misses.fetch_add(count, Ordering::Relaxed);
}
/// Record an error by kind (e.g., "not_found", "internal", "invalid_argument").
@@ -132,7 +126,6 @@ pub fn inc_error(kind: &str) {
.fetch_add(1, Ordering::Relaxed);
}
/// Render all metrics in Prometheus text exposition format.
pub fn render_metrics() -> String {
let m = metrics();
@@ -163,17 +156,15 @@ pub fn render_metrics() -> String {
let (method_and_status, count) = (entry.key(), entry.value());
let count = count.load(Ordering::Relaxed);
if let Some((method, status)) = method_and_status.rsplit_once(':') {
out.push_str(
&format!("gitks_requests_total{{method=\"{method}\",status=\"{status}\"}} {count}\n"),
);
out.push_str(&format!(
"gitks_requests_total{{method=\"{method}\",status=\"{status}\"}} {count}\n"
));
}
}
out.push('\n');
// Duration histogram
out.push_str(
"# HELP gitks_request_duration_milliseconds Request duration histogram in ms\n",
);
out.push_str("# HELP gitks_request_duration_milliseconds Request duration histogram in ms\n");
out.push_str("# TYPE gitks_request_duration_milliseconds histogram\n");
for entry in &m.duration_buckets {
let (method_and_bound, count) = (entry.key(), entry.value());
@@ -215,7 +206,6 @@ pub fn render_metrics() -> String {
out
}
/// Start the metrics HTTP server on the given port.
/// Runs in a background task; returns the JoinHandle.
pub fn start_metrics_server(port: u16) -> tokio::task::JoinHandle<()> {
@@ -256,12 +246,14 @@ async fn handle_metrics_connection(mut socket: tokio::net::TcpStream) {
body
);
let _ = tokio::time::timeout(Duration::from_secs(5), socket.write_all(response.as_bytes()))
.await;
let _ = tokio::time::timeout(
Duration::from_secs(5),
socket.write_all(response.as_bytes()),
)
.await;
let _ = socket.shutdown().await;
}
/// A guard that records metrics on drop.
///
/// Usage in handlers: