rnacos/raft/network/
management.rs

1use std::collections::HashSet;
2use std::sync::Arc;
3
4use actix_web::web::Data;
5use actix_web::web::Json;
6use actix_web::Responder;
7use async_raft_ext::raft::ClientWriteRequest;
8
9use crate::common::appdata::AppShareData;
10use crate::raft::join_node;
11use crate::raft::store::ClientRequest;
12use crate::raft::store::NodeId;
13
14// --- Cluster management
15
16pub async fn join_learner(
17    app: Data<Arc<AppShareData>>,
18    req: Json<(NodeId, String)>,
19) -> actix_web::Result<impl Responder> {
20    let node_id = req.0 .0;
21    let addr = Arc::new(req.0 .1);
22    app.raft
23        .client_write(ClientWriteRequest::new(ClientRequest::NodeAddr {
24            id: node_id,
25            addr,
26        }))
27        .await
28        .unwrap();
29    app.raft.add_non_voter(node_id).await.unwrap();
30    join_node(app.raft.as_ref(), app.raft_store.as_ref(), node_id)
31        .await
32        .ok();
33    Ok("{\"ok\":1}")
34}
35
36/// Add a node as **Learner**.
37///
38/// A Learner receives log replication from the leader but does not vote.
39/// This should be done before adding a node as a member into the cluster
40/// (by calling `change-membership`)
41//#[post("/add-learner")]
42pub async fn add_learner(
43    app: Data<Arc<AppShareData>>,
44    req: Json<(NodeId, String)>,
45) -> actix_web::Result<impl Responder> {
46    let node_id = req.0 .0;
47    let addr = Arc::new(req.0 .1);
48    app.raft
49        .client_write(ClientWriteRequest::new(ClientRequest::NodeAddr {
50            id: node_id,
51            addr,
52        }))
53        .await
54        .unwrap();
55    app.raft.add_non_voter(node_id).await.unwrap();
56    Ok("{\"ok\":1}")
57}
58
59/// Changes specified learners to members, or remove members.
60//#[post("/change-membership")]
61pub async fn change_membership(
62    app: Data<Arc<AppShareData>>,
63    req: Json<HashSet<NodeId>>,
64) -> actix_web::Result<impl Responder> {
65    app.raft.change_membership(req.0).await.unwrap();
66    Ok("{\"ok\":1}")
67}
68
69/// Initialize a single-node cluster.
70//#[post("/init")]
71pub async fn init(app: Data<Arc<AppShareData>>) -> actix_web::Result<impl Responder> {
72    let mut members = HashSet::new();
73    let node_id = app.sys_config.raft_node_id.to_owned();
74    members.insert(node_id);
75    app.raft.initialize(members).await.ok();
76    app.raft
77        .client_write(ClientWriteRequest::new(ClientRequest::NodeAddr {
78            id: node_id,
79            addr: Arc::new(app.sys_config.raft_node_addr.to_owned()),
80        }))
81        .await
82        .unwrap();
83    Ok("{\"ok\":1}")
84}
85
86/// Get the latest metrics of the cluster
87//#[get("/metrics")]
88pub async fn metrics(app: Data<Arc<AppShareData>>) -> actix_web::Result<impl Responder> {
89    let metrics = app.raft.metrics().borrow().clone();
90    Ok(Json(metrics))
91}