pub use anyhow::Result;
use client::Clerk;
use parking_lot::Mutex;
use ruaft::rpcs::register_server;
use ruaft::RpcClient;
use server::KVServer;
use std::sync::Arc;
use testing_utils::memory_persister::MemoryStorage;
use testing_utils::rpcs::register_kv_server;
struct ConfigState {
kv_servers: Vec>>,
clerks: Vec >,
}
pub struct Config {
network: Arc>,
server_count: usize,
state: Mutex,
storage: MemoryStorage,
maxraftstate: usize,
}
impl Config {
fn kv_server_name(i: usize) -> String {
format!("kv-server-{}", i)
}
fn server_name(i: usize) -> String {
format!("kvraft-server-{}", i)
}
fn client_name(client: usize, server: usize) -> String {
format!("kvraft-client-{}-to-{}", client, server)
}
fn start_server(&self, index: usize) -> Result<()> {
let mut clients = vec![];
{
let mut network = self.network.lock();
for j in 0..self.server_count {
clients.push(RpcClient::new(network.make_client(
Self::client_name(index, j),
Self::server_name(j),
)))
}
}
let persister = self.storage.at(index);
let kv = KVServer::new(clients, index, persister);
self.state.lock().kv_servers[index].replace(kv.clone());
let raft = std::rc::Rc::new(kv.raft());
register_server(raft, Self::server_name(index), self.network.as_ref())?;
register_kv_server(
kv,
Self::kv_server_name(index),
self.network.as_ref(),
)?;
Ok(())
}
}
pub fn make_config(
server_count: usize,
unreliable: bool,
maxraftstate: usize,
) -> Config {
let network = labrpc::Network::run_daemon();
{
let mut unlocked_network = network.lock();
unlocked_network.set_reliable(!unreliable);
unlocked_network.set_long_delays(true);
}
let state = Mutex::new(ConfigState {
kv_servers: vec![None; server_count],
clerks: vec![],
});
let mut storage = MemoryStorage::default();
for _ in 0..server_count {
storage.make();
}
let cfg = Config {
network,
server_count,
state,
storage,
maxraftstate,
};
for i in 0..server_count {
cfg.start_server(i)
.expect("Starting server should not fail");
}
cfg
}