Split code for modular compilation

This commit is contained in:
Alex Auvolat 2020-04-24 10:10:01 +00:00
parent 51fb3799a1
commit d8f5e643bc
39 changed files with 569 additions and 281 deletions

111
Cargo.lock generated
View file

@ -315,32 +315,133 @@ dependencies = [
[[package]] [[package]]
name = "garage" name = "garage"
version = "0.1.0" version = "0.1.0"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"garage_api 0.1.0",
"garage_core 0.1.0",
"garage_rpc 0.1.0",
"garage_table 0.1.0",
"garage_util 0.1.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "garage_api"
version = "0.1.0"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"garage_core 0.1.0",
"garage_table 0.1.0",
"garage_util 0.1.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "garage_core"
version = "0.1.0"
dependencies = [ dependencies = [
"arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"garage_rpc 0.1.0",
"garage_table 0.1.0",
"garage_util 0.1.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "garage_rpc"
version = "0.1.0"
dependencies = [
"arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"garage_util 0.1.0",
"gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-rustls 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "garage_table"
version = "0.1.0"
dependencies = [
"arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"garage_rpc 0.1.0",
"garage_util 0.1.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "garage_util"
version = "0.1.0"
dependencies = [
"err-derive 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", "sled 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View file

@ -1,44 +1,12 @@
[package] [workspace]
name = "garage" members = [
version = "0.1.0" "src/util",
authors = ["Alex Auvolat <alex@adnab.me>"] "src/rpc",
edition = "2018" "src/table",
"src/core",
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html "src/api",
"src/garage",
[dependencies] ]
bytes = "0.4"
rand = "0.7"
hex = "0.3"
sha2 = "0.8"
arc-swap = "0.4"
gethostname = "0.2"
err-derive = "0.2.3"
log = "0.4"
pretty_env_logger = "0.4"
sled = "0.31"
structopt = { version = "0.3", default-features = false }
toml = "0.5"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_bytes = "0.11"
serde_json = "1.0"
async-trait = "0.1.30"
futures = "0.3"
futures-core = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }
http = "0.2"
hyper = "0.13"
rustls = "0.17"
tokio-rustls = "0.13"
hyper-rustls = { version = "0.20", default-features = false }
webpki = "0.21"
[profile.dev] [profile.dev]
lto = "off" lto = "off"

View file

@ -1,3 +1,3 @@
all: all:
cargo fmt || true cargo fmt || true
cargo build RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo build

28
src/api/Cargo.toml Normal file
View file

@ -0,0 +1,28 @@
[package]
name = "garage_api"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[lib]
path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
garage_util = { path = "../util" }
garage_table = { path = "../table" }
garage_core = { path = "../core" }
bytes = "0.4"
hex = "0.3"
log = "0.4"
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }
http = "0.2"
hyper = "0.13"

View file

@ -9,18 +9,18 @@ use hyper::server::conn::AddrStream;
use hyper::service::{make_service_fn, service_fn}; use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode}; use hyper::{Body, Method, Request, Response, Server, StatusCode};
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::server::Garage;
use crate::table::EmptyKey; use garage_table::EmptyKey;
use crate::store::block::INLINE_THRESHOLD; use garage_core::block::INLINE_THRESHOLD;
use crate::store::block_ref_table::*; use garage_core::block_ref_table::*;
use crate::store::object_table::*; use garage_core::garage::Garage;
use crate::store::version_table::*; use garage_core::object_table::*;
use garage_core::version_table::*;
use crate::api::http_util::*; use crate::http_util::*;
type BodyType = Box<dyn HttpBody<Data = Bytes, Error = Error> + Send + Unpin>; type BodyType = Box<dyn HttpBody<Data = Bytes, Error = Error> + Send + Unpin>;

View file

@ -5,7 +5,7 @@ use futures::ready;
use futures::stream::*; use futures::stream::*;
use hyper::body::{Bytes, HttpBody}; use hyper::body::{Bytes, HttpBody};
use crate::error::Error; use garage_util::error::Error;
type StreamType = Pin<Box<dyn Stream<Item = Result<Bytes, Error>> + Send>>; type StreamType = Pin<Box<dyn Stream<Item = Result<Bytes, Error>> + Send>>;

View file

@ -1,2 +1,5 @@
#[macro_use]
extern crate log;
pub mod api_server; pub mod api_server;
pub mod http_util; pub mod http_util;

34
src/core/Cargo.toml Normal file
View file

@ -0,0 +1,34 @@
[package]
name = "garage_core"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[lib]
path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
garage_util = { path = "../util" }
garage_rpc = { path = "../rpc" }
garage_table = { path = "../table" }
bytes = "0.4"
rand = "0.7"
hex = "0.3"
sha2 = "0.8"
arc-swap = "0.4"
log = "0.4"
sled = "0.31"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_bytes = "0.11"
async-trait = "0.1.30"
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }

View file

@ -11,20 +11,20 @@ use tokio::fs;
use tokio::prelude::*; use tokio::prelude::*;
use tokio::sync::{watch, Mutex, Notify}; use tokio::sync::{watch, Mutex, Notify};
use crate::data; use garage_util::data;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::rpc::membership::System; use garage_rpc::membership::System;
use crate::rpc::rpc_client::*; use garage_rpc::rpc_client::*;
use crate::rpc::rpc_server::*; use garage_rpc::rpc_server::*;
use crate::table::table_sharded::TableShardedReplication; use garage_table::table_sharded::TableShardedReplication;
use crate::table::TableReplication; use garage_table::TableReplication;
use crate::store::block_ref_table::*; use crate::block_ref_table::*;
use crate::server::Garage; use crate::garage::Garage;
pub const INLINE_THRESHOLD: usize = 3072; pub const INLINE_THRESHOLD: usize = 3072;

View file

@ -2,13 +2,13 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
use crate::background::*; use garage_util::background::*;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::table::*; use garage_table::*;
use crate::store::block::*; use crate::block::*;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct BlockRef { pub struct BlockRef {

View file

@ -1,8 +1,8 @@
use async_trait::async_trait; use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::error::Error; use garage_table::*;
use crate::table::*; use garage_util::error::Error;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct Bucket { pub struct Bucket {

View file

@ -1,31 +1,22 @@
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use futures_util::future::*; use garage_util::background::*;
use tokio::sync::watch; use garage_util::config::*;
use crate::background::*; use garage_rpc::membership::System;
use crate::config::*; use garage_rpc::rpc_client::RpcHttpClient;
use crate::error::Error; use garage_rpc::rpc_server::RpcServer;
use crate::rpc::membership::System; use garage_table::table_fullcopy::*;
use crate::rpc::rpc_client::RpcHttpClient; use garage_table::table_sharded::*;
use crate::rpc::rpc_server::RpcServer; use garage_table::*;
use crate::table::table_fullcopy::*; use crate::block::*;
use crate::table::table_sharded::*; use crate::block_ref_table::*;
use crate::table::*; use crate::bucket_table::*;
use crate::key_table::*;
use crate::store::block::*; use crate::object_table::*;
use crate::store::block_ref_table::*; use crate::version_table::*;
use crate::store::bucket_table::*;
use crate::store::key_table::*;
use crate::store::object_table::*;
use crate::store::version_table::*;
use crate::api::api_server;
use crate::admin_rpc::*;
pub struct Garage { pub struct Garage {
pub config: Config, pub config: Config,
@ -166,9 +157,6 @@ impl Garage {
block_ref_table, block_ref_table,
}); });
info!("Crate admin RPC handler...");
AdminRpcHandler::new(garage.clone()).register_handler(rpc_server);
info!("Start block manager background thread..."); info!("Start block manager background thread...");
garage.block_manager.garage.swap(Some(garage.clone())); garage.block_manager.garage.swap(Some(garage.clone()));
garage.block_manager.clone().spawn_background_worker().await; garage.block_manager.clone().spawn_background_worker().await;
@ -176,72 +164,3 @@ impl Garage {
garage garage
} }
} }
async fn shutdown_signal(send_cancel: watch::Sender<bool>) -> Result<(), Error> {
// Wait for the CTRL+C signal
tokio::signal::ctrl_c()
.await
.expect("failed to install CTRL+C signal handler");
info!("Received CTRL+C, shutting down.");
send_cancel.broadcast(true)?;
Ok(())
}
async fn wait_from(mut chan: watch::Receiver<bool>) -> () {
while let Some(exit_now) = chan.recv().await {
if exit_now {
return;
}
}
}
pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
info!("Loading configuration...");
let config = read_config(config_file).expect("Unable to read config file");
info!("Opening database...");
let mut db_path = config.metadata_dir.clone();
db_path.push("db");
let db = sled::open(db_path).expect("Unable to open DB");
info!("Initialize RPC server...");
let mut rpc_server = RpcServer::new(config.rpc_bind_addr.clone(), config.rpc_tls.clone());
info!("Initializing background runner...");
let (send_cancel, watch_cancel) = watch::channel(false);
let background = BackgroundRunner::new(16, watch_cancel.clone());
let garage = Garage::new(config, db, background.clone(), &mut rpc_server).await;
info!("Initializing RPC and API servers...");
let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone()));
let api_server = api_server::run_api_server(garage.clone(), wait_from(watch_cancel.clone()));
futures::try_join!(
garage
.system
.clone()
.bootstrap(&garage.config.bootstrap_peers[..])
.map(|rv| {
info!("Bootstrap done");
Ok(rv)
}),
run_rpc_server.map(|rv| {
info!("RPC server exited");
rv
}),
api_server.map(|rv| {
info!("API server exited");
rv
}),
background.run().map(|rv| {
info!("Background runner exited");
Ok(rv)
}),
shutdown_signal(send_cancel),
)?;
info!("Cleaning up...");
Ok(())
}

View file

@ -1,9 +1,9 @@
use async_trait::async_trait; use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::data::*; use garage_table::*;
use crate::error::Error; use garage_util::data::*;
use crate::table::*; use garage_util::error::Error;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct Key { pub struct Key {

View file

@ -1,7 +1,10 @@
#[macro_use]
extern crate log;
pub mod block; pub mod block;
pub mod block_ref_table; pub mod block_ref_table;
pub mod bucket_table; pub mod bucket_table;
pub mod garage;
pub mod key_table; pub mod key_table;
pub mod object_table; pub mod object_table;
pub mod repair;
pub mod version_table; pub mod version_table;

View file

@ -2,14 +2,14 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
use crate::background::BackgroundRunner; use garage_util::background::BackgroundRunner;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::table::table_sharded::*; use garage_table::table_sharded::*;
use crate::table::*; use garage_table::*;
use crate::store::version_table::*; use crate::version_table::*;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct Object { pub struct Object {

View file

@ -2,14 +2,14 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
use crate::background::BackgroundRunner; use garage_util::background::BackgroundRunner;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::table::table_sharded::*; use garage_table::table_sharded::*;
use crate::table::*; use garage_table::*;
use crate::store::block_ref_table::*; use crate::block_ref_table::*;
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub struct Version { pub struct Version {

36
src/garage/Cargo.toml Normal file
View file

@ -0,0 +1,36 @@
[package]
name = "garage"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[[bin]]
name = "garage"
path = "main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
garage_util = { path = "../util" }
garage_rpc = { path = "../rpc" }
garage_table = { path = "../table" }
garage_core = { path = "../core" }
garage_api = { path = "../api" }
bytes = "0.4"
rand = "0.7"
hex = "0.3"
sha2 = "0.8"
log = "0.4"
pretty_env_logger = "0.4"
sled = "0.31"
structopt = { version = "0.3", default-features = false }
toml = "0.5"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }

View file

@ -2,19 +2,19 @@ use std::sync::Arc;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::server::Garage;
use crate::table::*; use garage_table::*;
use crate::rpc::rpc_client::*; use garage_rpc::rpc_client::*;
use crate::rpc::rpc_server::*; use garage_rpc::rpc_server::*;
use crate::store::bucket_table::*; use garage_core::bucket_table::*;
use crate::store::key_table::*; use garage_core::garage::Garage;
use crate::store::repair::Repair; use garage_core::key_table::*;
use crate::repair::Repair;
use crate::*; use crate::*;
pub const ADMIN_RPC_TIMEOUT: Duration = Duration::from_secs(30); pub const ADMIN_RPC_TIMEOUT: Duration = Duration::from_secs(30);

View file

@ -3,17 +3,8 @@
#[macro_use] #[macro_use]
extern crate log; extern crate log;
mod background;
mod config;
mod data;
mod error;
mod api;
mod rpc;
mod store;
mod table;
mod admin_rpc; mod admin_rpc;
mod repair;
mod server; mod server;
use std::collections::HashSet; use std::collections::HashSet;
@ -25,12 +16,12 @@ use std::time::Duration;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use structopt::StructOpt; use structopt::StructOpt;
use config::TlsConfig; use garage_util::config::TlsConfig;
use data::*; use garage_util::data::*;
use error::Error; use garage_util::error::Error;
use rpc::membership::*; use garage_rpc::membership::*;
use rpc::rpc_client::*; use garage_rpc::rpc_client::*;
use admin_rpc::*; use admin_rpc::*;

View file

@ -2,12 +2,11 @@ use std::sync::Arc;
use tokio::sync::watch; use tokio::sync::watch;
use crate::error::Error; use garage_core::block_ref_table::*;
use crate::server::Garage; use garage_core::garage::Garage;
use crate::table::*; use garage_core::version_table::*;
use garage_table::*;
use crate::store::block_ref_table::*; use garage_util::error::Error;
use crate::store::version_table::*;
use crate::*; use crate::*;

87
src/garage/server.rs Normal file
View file

@ -0,0 +1,87 @@
use std::path::PathBuf;
use std::sync::Arc;
use futures_util::future::*;
use tokio::sync::watch;
use garage_util::background::*;
use garage_util::config::*;
use garage_util::error::Error;
use garage_api::api_server;
use garage_core::garage::Garage;
use garage_rpc::rpc_server::RpcServer;
use crate::admin_rpc::*;
async fn shutdown_signal(send_cancel: watch::Sender<bool>) -> Result<(), Error> {
// Wait for the CTRL+C signal
tokio::signal::ctrl_c()
.await
.expect("failed to install CTRL+C signal handler");
info!("Received CTRL+C, shutting down.");
send_cancel.broadcast(true)?;
Ok(())
}
async fn wait_from(mut chan: watch::Receiver<bool>) -> () {
while let Some(exit_now) = chan.recv().await {
if exit_now {
return;
}
}
}
pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
info!("Loading configuration...");
let config = read_config(config_file).expect("Unable to read config file");
info!("Opening database...");
let mut db_path = config.metadata_dir.clone();
db_path.push("db");
let db = sled::open(db_path).expect("Unable to open DB");
info!("Initialize RPC server...");
let mut rpc_server = RpcServer::new(config.rpc_bind_addr.clone(), config.rpc_tls.clone());
info!("Initializing background runner...");
let (send_cancel, watch_cancel) = watch::channel(false);
let background = BackgroundRunner::new(16, watch_cancel.clone());
let garage = Garage::new(config, db, background.clone(), &mut rpc_server).await;
info!("Crate admin RPC handler...");
AdminRpcHandler::new(garage.clone()).register_handler(&mut rpc_server);
info!("Initializing RPC and API servers...");
let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone()));
let api_server = api_server::run_api_server(garage.clone(), wait_from(watch_cancel.clone()));
futures::try_join!(
garage
.system
.clone()
.bootstrap(&garage.config.bootstrap_peers[..])
.map(|rv| {
info!("Bootstrap done");
Ok(rv)
}),
run_rpc_server.map(|rv| {
info!("RPC server exited");
rv
}),
api_server.map(|rv| {
info!("API server exited");
rv
}),
background.run().map(|rv| {
info!("Background runner exited");
Ok(rv)
}),
shutdown_signal(send_cancel),
)?;
info!("Cleaning up...");
Ok(())
}

37
src/rpc/Cargo.toml Normal file
View file

@ -0,0 +1,37 @@
[package]
name = "garage_rpc"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[lib]
path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
garage_util = { path = "../util" }
bytes = "0.4"
rand = "0.7"
hex = "0.3"
sha2 = "0.8"
arc-swap = "0.4"
gethostname = "0.2"
log = "0.4"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }
http = "0.2"
hyper = "0.13"
rustls = "0.17"
tokio-rustls = "0.13"
hyper-rustls = { version = "0.20", default-features = false }
webpki = "0.21"

View file

@ -1,3 +1,6 @@
#[macro_use]
extern crate log;
pub mod membership; pub mod membership;
pub mod rpc_client; pub mod rpc_client;
pub mod rpc_server; pub mod rpc_server;

View file

@ -17,12 +17,12 @@ use tokio::prelude::*;
use tokio::sync::watch; use tokio::sync::watch;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use crate::background::BackgroundRunner; use garage_util::background::BackgroundRunner;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::rpc::rpc_client::*; use crate::rpc_client::*;
use crate::rpc::rpc_server::*; use crate::rpc_server::*;
const PING_INTERVAL: Duration = Duration::from_secs(10); const PING_INTERVAL: Duration = Duration::from_secs(10);
const PING_TIMEOUT: Duration = Duration::from_secs(2); const PING_TIMEOUT: Duration = Duration::from_secs(2);

View file

@ -8,7 +8,6 @@ use std::time::Duration;
use arc_swap::ArcSwapOption; use arc_swap::ArcSwapOption;
use bytes::IntoBuf; use bytes::IntoBuf;
use err_derive::Error;
use futures::future::Future; use futures::future::Future;
use futures::stream::futures_unordered::FuturesUnordered; use futures::stream::futures_unordered::FuturesUnordered;
use futures::stream::StreamExt; use futures::stream::StreamExt;
@ -17,36 +16,17 @@ use hyper::client::{Client, HttpConnector};
use hyper::{Body, Method, Request}; use hyper::{Body, Method, Request};
use tokio::sync::{watch, Semaphore}; use tokio::sync::{watch, Semaphore};
use crate::background::BackgroundRunner; use garage_util::background::BackgroundRunner;
use crate::data::*; use garage_util::config::TlsConfig;
use crate::error::Error; use garage_util::data::*;
use garage_util::error::{Error, RPCError};
use crate::rpc::membership::Status; use crate::membership::Status;
use crate::rpc::rpc_server::RpcMessage; use crate::rpc_server::RpcMessage;
use crate::rpc::tls_util; use crate::tls_util;
use crate::config::TlsConfig;
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10); const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
#[derive(Debug, Error)]
pub enum RPCError {
#[error(display = "Node is down: {:?}.", _0)]
NodeDown(UUID),
#[error(display = "Timeout: {}", _0)]
Timeout(#[error(source)] tokio::time::Elapsed),
#[error(display = "HTTP error: {}", _0)]
HTTP(#[error(source)] http::Error),
#[error(display = "Hyper error: {}", _0)]
Hyper(#[error(source)] hyper::Error),
#[error(display = "Messagepack encode error: {}", _0)]
RMPEncode(#[error(source)] rmp_serde::encode::Error),
#[error(display = "Messagepack decode error: {}", _0)]
RMPDecode(#[error(source)] rmp_serde::decode::Error),
#[error(display = "Too many errors: {:?}", _0)]
TooManyErrors(Vec<String>),
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct RequestStrategy { pub struct RequestStrategy {
pub rs_timeout: Duration, pub rs_timeout: Duration,

View file

@ -16,11 +16,11 @@ use tokio::net::{TcpListener, TcpStream};
use tokio_rustls::server::TlsStream; use tokio_rustls::server::TlsStream;
use tokio_rustls::TlsAcceptor; use tokio_rustls::TlsAcceptor;
use crate::config::TlsConfig; use garage_util::config::TlsConfig;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::rpc::tls_util; use crate::tls_util;
pub trait RpcMessage: Serialize + for<'de> Deserialize<'de> + Send + Sync {} pub trait RpcMessage: Serialize + for<'de> Deserialize<'de> + Send + Sync {}

View file

@ -15,7 +15,7 @@ use tokio::io::{AsyncRead, AsyncWrite};
use tokio_rustls::TlsConnector; use tokio_rustls::TlsConnector;
use webpki::DNSNameRef; use webpki::DNSNameRef;
use crate::error::Error; use garage_util::error::Error;
pub fn load_certs(filename: &str) -> Result<Vec<rustls::Certificate>, Error> { pub fn load_certs(filename: &str) -> Result<Vec<rustls::Certificate>, Error> {
let certfile = fs::File::open(&filename)?; let certfile = fs::File::open(&filename)?;

32
src/table/Cargo.toml Normal file
View file

@ -0,0 +1,32 @@
[package]
name = "garage_table"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[lib]
path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
garage_util = { path = "../util" }
garage_rpc = { path = "../rpc" }
bytes = "0.4"
rand = "0.7"
hex = "0.3"
arc-swap = "0.4"
log = "0.4"
sled = "0.31"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_bytes = "0.11"
async-trait = "0.1.30"
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }

View file

@ -1,3 +1,8 @@
#![recursion_limit = "1024"]
#[macro_use]
extern crate log;
pub mod table; pub mod table;
pub mod table_fullcopy; pub mod table_fullcopy;
pub mod table_sharded; pub mod table_sharded;

View file

@ -8,14 +8,14 @@ use futures::stream::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf; use serde_bytes::ByteBuf;
use crate::data::*; use garage_util::data::*;
use crate::error::Error; use garage_util::error::Error;
use crate::rpc::membership::{Ring, System}; use garage_rpc::membership::{Ring, System};
use crate::rpc::rpc_client::*; use garage_rpc::rpc_client::*;
use crate::rpc::rpc_server::*; use garage_rpc::rpc_server::*;
use crate::table::table_sync::*; use crate::table_sync::*;
const TABLE_RPC_TIMEOUT: Duration = Duration::from_secs(10); const TABLE_RPC_TIMEOUT: Duration = Duration::from_secs(10);
@ -78,14 +78,14 @@ impl PartitionKey for EmptyKey {
} }
} }
impl<T: AsRef<str>> PartitionKey for T { impl PartitionKey for String {
fn hash(&self) -> Hash { fn hash(&self) -> Hash {
hash(self.as_ref().as_bytes()) hash(self.as_bytes())
} }
} }
impl<T: AsRef<str>> SortKey for T { impl SortKey for String {
fn sort_key(&self) -> &[u8] { fn sort_key(&self) -> &[u8] {
self.as_ref().as_bytes() self.as_bytes()
} }
} }

View file

@ -1,9 +1,10 @@
use arc_swap::ArcSwapOption; use arc_swap::ArcSwapOption;
use std::sync::Arc; use std::sync::Arc;
use crate::data::*; use garage_rpc::membership::{Ring, System};
use crate::rpc::membership::{Ring, System}; use garage_util::data::*;
use crate::table::*;
use crate::*;
#[derive(Clone)] #[derive(Clone)]
pub struct TableFullReplication { pub struct TableFullReplication {

View file

@ -1,6 +1,7 @@
use crate::data::*; use garage_rpc::membership::{Ring, System};
use crate::rpc::membership::{Ring, System}; use garage_util::data::*;
use crate::table::*;
use crate::*;
#[derive(Clone)] #[derive(Clone)]
pub struct TableShardedReplication { pub struct TableShardedReplication {

View file

@ -12,10 +12,11 @@ use serde_bytes::ByteBuf;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::sync::{mpsc, watch}; use tokio::sync::{mpsc, watch};
use crate::data::*; use garage_rpc::membership::Ring;
use crate::error::Error; use garage_util::data::*;
use crate::rpc::membership::Ring; use garage_util::error::Error;
use crate::table::*;
use crate::*;
const MAX_DEPTH: usize = 16; const MAX_DEPTH: usize = 16;
const SCAN_INTERVAL: Duration = Duration::from_secs(3600); const SCAN_INTERVAL: Duration = Duration::from_secs(3600);

35
src/util/Cargo.toml Normal file
View file

@ -0,0 +1,35 @@
[package]
name = "garage_util"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
[lib]
path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.7"
hex = "0.3"
sha2 = "0.8"
err-derive = "0.2.3"
log = "0.4"
sled = "0.31"
toml = "0.5"
rmp-serde = "0.14.3"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_json = "1.0"
futures = "0.3"
futures-util = "0.3"
tokio = { version = "0.2", default-features = false, features = ["rt-core", "rt-threaded", "io-driver", "net", "tcp", "time", "macros", "sync", "signal", "fs"] }
http = "0.2"
hyper = "0.13"
rustls = "0.17"
webpki = "0.21"

View file

@ -34,6 +34,13 @@ pub struct Config {
pub rpc_tls: Option<TlsConfig>, pub rpc_tls: Option<TlsConfig>,
} }
#[derive(Deserialize, Debug, Clone)]
pub struct TlsConfig {
pub ca_cert: String,
pub node_cert: String,
pub node_key: String,
}
fn default_max_concurrent_rpc_requests() -> usize { fn default_max_concurrent_rpc_requests() -> usize {
12 12
} }
@ -47,13 +54,6 @@ fn default_epidemic_factor() -> usize {
3 3
} }
#[derive(Deserialize, Debug, Clone)]
pub struct TlsConfig {
pub ca_cert: String,
pub node_cert: String,
pub node_key: String,
}
pub fn read_config(config_file: PathBuf) -> Result<Config, Error> { pub fn read_config(config_file: PathBuf) -> Result<Config, Error> {
let mut file = std::fs::OpenOptions::new() let mut file = std::fs::OpenOptions::new()
.read(true) .read(true)

View file

@ -2,8 +2,25 @@ use err_derive::Error;
use hyper::StatusCode; use hyper::StatusCode;
use std::io; use std::io;
use crate::data::Hash; use crate::data::*;
use crate::rpc::rpc_client::RPCError;
#[derive(Debug, Error)]
pub enum RPCError {
#[error(display = "Node is down: {:?}.", _0)]
NodeDown(UUID),
#[error(display = "Timeout: {}", _0)]
Timeout(#[error(source)] tokio::time::Elapsed),
#[error(display = "HTTP error: {}", _0)]
HTTP(#[error(source)] http::Error),
#[error(display = "Hyper error: {}", _0)]
Hyper(#[error(source)] hyper::Error),
#[error(display = "Messagepack encode error: {}", _0)]
RMPEncode(#[error(source)] rmp_serde::encode::Error),
#[error(display = "Messagepack decode error: {}", _0)]
RMPDecode(#[error(source)] rmp_serde::decode::Error),
#[error(display = "Too many errors: {:?}", _0)]
TooManyErrors(Vec<String>),
}
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum Error { pub enum Error {

7
src/util/lib.rs Normal file
View file

@ -0,0 +1,7 @@
#[macro_use]
extern crate log;
pub mod background;
pub mod config;
pub mod data;
pub mod error;