Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
835 changes: 390 additions & 445 deletions Cargo.lock

Large diffs are not rendered by default.

39 changes: 18 additions & 21 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ percas-cluster = { version = "0.2.1", path = "crates/cluster" }
percas-core = { version = "0.2.1", path = "crates/core" }
percas-metrics = { version = "0.2.1", path = "crates/metrics" }
percas-server = { version = "0.2.1", path = "crates/server" }
percas-styled = { version = "0.2.1", path = "crates/styled" }
percas-version = { version = "0.2.1", path = "crates/version" }
tests-toolkit = { version = "0.2.1", path = "tests/toolkit" }

Expand All @@ -53,40 +52,38 @@ backon = { version = "1.5.0" }
build-data = { version = "0.3.0" }
clap = { version = "4.5.35", features = ["derive"] }
const_format = { version = "0.2.34" }
criterion = { version = "0.6.0", features = ["async_tokio"] }
criterion = { version = "0.7.0", features = ["async_tokio"] }
ctrlc = { version = "3.4", features = ["termination"] }
error-stack = { version = "0.5", default-features = false, features = [
"std",
"serde",
] }
exn = { version = "0.1.0-alpha.5" }
fastimer = { version = "0.9.0" }
fastrace = { version = "0.7.9" }
fastrace-opentelemetry = { version = "0.10.0" }
foyer = { version = "0.17.3", features = ["nightly"] }
fastrace-opentelemetry = { version = "0.13.0" }
foyer = { version = "0.18.0", features = ["nightly"] }
futures-util = { version = "0.3.31" }
gix-discover = { version = "0.40.1" }
gix-discover = { version = "0.41.0" }
googletest = { version = "0.14.0" }
humansize = { version = "2.1.3" }
indent = { version = "0.1.1" }
insta = { version = "1.42.2" }
jiff = { version = "0.2", features = ["serde"] }
local-ip-address = { version = "0.6.3" }
log = { version = "0.4.27", features = ["kv"] }
logforth = { version = "0.24.0", features = [
logforth = { version = "0.26.0", features = [
"colored",
"fastrace",
"json",
"opentelemetry",
"rolling-file",
"append-fastrace",
"append-opentelemetry",
"append-rolling-file",
"diagnostic-fastrace",
"layout-json",
] }
mea = { version = "0.3.5" }
opentelemetry = { version = "0.29.1", features = ["trace", "metrics"] }
opentelemetry-otlp = { version = "0.29.0", features = [
mea = { version = "0.3.11" }
opentelemetry = { version = "0.30.0", features = ["trace", "metrics"] }
opentelemetry-otlp = { version = "0.30.0", features = [
"trace",
"metrics",
"grpc-tonic",
] }
opentelemetry_sdk = { version = "0.29.0", features = [
opentelemetry_sdk = { version = "0.30.0", features = [
"trace",
"metrics",
"rt-tokio",
Expand All @@ -97,19 +94,19 @@ pretty-hex = { version = "0.4.1" }
pretty_assertions = { version = "1.4.1" }
regex = { version = "1.11.1" }
reqwest = { version = "0.12.15", default-features = false, features = ["json"] }
schemars = { version = "1.0.0-alpha.18", features = ["jiff02"] }
schemars = { version = "1.0.4", features = ["jiff02"] }
scopeguard = { version = "1.2.0" }
sealed_test = { version = "1.1" }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
sha2 = { version = "0.10.8" }
shadow-rs = { version = "1.0.0", default-features = false }
sysinfo = { version = "0.35.0" }
sysinfo = { version = "0.36.1" }
tempfile = { version = "3.19.1" }
test-harness = { version = "0.3.0" }
thiserror = { version = "2.0" }
tokio = { version = "1.44.2" }
toml_edit = { version = "0.22.22" }
toml_edit = { version = "0.23.2" }
unindent = { version = "0.2.4" }
uuid = { version = "1.16.0", features = ["v4", "serde"] }

Expand Down
1 change: 0 additions & 1 deletion api/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ repository.workspace = true
version.workspace = true

[dependencies]
error-stack = { workspace = true }
reqwest = { workspace = true }
thiserror = { workspace = true }

Expand Down
4 changes: 2 additions & 2 deletions cmd/percas/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ version.workspace = true
release = false

[dependencies]
anstyle = { workspace = true }
clap = { workspace = true }
ctrlc = { workspace = true }
error-stack = { workspace = true }
exn = { workspace = true }
log = { workspace = true }
mea = { workspace = true }
percas-cluster = { workspace = true }
percas-core = { workspace = true }
percas-server = { workspace = true }
percas-styled = { workspace = true }
percas-version = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
Expand Down
24 changes: 12 additions & 12 deletions cmd/percas/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
use std::path::PathBuf;
use std::str::FromStr;

use error_stack::Result;
use error_stack::ResultExt;
use error_stack::bail;
use exn::Result;
use exn::ResultExt;
use exn::bail;
use percas_core::Config;
use percas_core::known_option_entries;
use serde::Deserialize;
Expand All @@ -34,14 +34,14 @@ pub struct LoadConfigResult {

pub fn load_config(config_file: PathBuf) -> Result<LoadConfigResult, Error> {
// Layer 0: the config file
let content = std::fs::read_to_string(&config_file).change_context_lazy(|| {
let content = std::fs::read_to_string(&config_file).or_raise(|| {
Error(format!(
"failed to read config file: {}",
config_file.display()
))
})?;
let mut config = DocumentMut::from_str(&content)
.change_context_lazy(|| Error("failed to parse config content".to_string()))?;
.or_raise(|| Error("failed to parse config content".to_string()))?;

// Layer 1: environment variables
let env = std::env::vars()
Expand Down Expand Up @@ -91,17 +91,17 @@ pub fn load_config(config_file: PathBuf) -> Result<LoadConfigResult, Error> {
}
"integer" => {
let path = ent.ent_path;
let value = v.parse::<i64>().change_context_lazy(|| {
Error(format!("failed to parse integer value {v} of key {k}"))
})?;
let value = v
.parse::<i64>()
.or_raise(|| Error(format!("failed to parse integer value {v} of key {k}")))?;
let value = toml_edit::value(value);
(path, value)
}
"boolean" => {
let path = ent.ent_path;
let value = v.parse::<bool>().change_context_lazy(|| {
Error(format!("failed to parse boolean value {v} of key {k}"))
})?;
let value = v
.parse::<bool>()
.or_raise(|| Error(format!("failed to parse boolean value {v} of key {k}")))?;
let value = toml_edit::value(value);
(path, value)
}
Expand All @@ -116,7 +116,7 @@ pub fn load_config(config_file: PathBuf) -> Result<LoadConfigResult, Error> {
}

let config = Config::deserialize(config.into_deserializer())
.change_context_lazy(|| Error("failed to deserialize config".to_string()))?;
.or_raise(|| Error("failed to deserialize config".to_string()))?;
Ok(LoadConfigResult { config, warnings })
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/percas/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
// limitations under the License.

use clap::Parser;
use error_stack::Result;
use percas_styled::styled;
use exn::Result;
use percas_version::version;
use thiserror::Error;

mod config;
mod start;
mod styled;

#[derive(Debug, clap::Parser)]
#[command(name = "percas", version, long_version = version(), styles=styled())]
#[command(name = "percas", version, long_version = version(), styles=styled::styled())]
struct Command {
#[clap(subcommand)]
cmd: SubCommand,
Expand Down
25 changes: 11 additions & 14 deletions cmd/percas/src/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use std::path::PathBuf;
use std::sync::Arc;

use clap::ValueHint;
use error_stack::Result;
use error_stack::ResultExt;
use exn::Result;
use exn::ResultExt;
use mea::shutdown::ShutdownRecv;
use percas_cluster::GossipFuture;
use percas_cluster::GossipState;
Expand Down Expand Up @@ -46,9 +46,6 @@ pub struct CommandStart {

impl CommandStart {
pub fn run(self) -> Result<(), Error> {
// Configure error stack to not print with colors
error_stack::Report::set_color_mode(error_stack::fmt::ColorMode::None);

let LoadConfigResult { config, warnings } = load_config(self.config_file)?;

let telemetry_runtime = make_telemetry_runtime();
Expand Down Expand Up @@ -146,7 +143,7 @@ async fn run_server(server_rt: &Runtime, gossip_rt: &Runtime, config: Config) ->
config.storage.disk_throttle,
)
.await
.change_context_lazy(make_error)?;
.or_raise(make_error)?;

let (shutdown_tx, shutdown_rx) = mea::shutdown::new_pair();
let ctx = Arc::new(PercasContext { engine });
Expand All @@ -158,7 +155,7 @@ async fn run_server(server_rt: &Runtime, gossip_rt: &Runtime, config: Config) ->
flatten_config.advertise_addr.as_deref(),
)
.await
.change_context_lazy(make_error)?;
.or_raise(make_error)?;

let (cluster_proxy, gossip_futs) = match flatten_config.mode {
ServerMode::Standalone => (None, vec![]),
Expand All @@ -181,10 +178,10 @@ async fn run_server(server_rt: &Runtime, gossip_rt: &Runtime, config: Config) ->
gossip_futs,
)
.await
.change_context_lazy(|| Error("A fatal error has occurred in server process.".to_string()))?;
.or_raise(|| Error("A fatal error has occurred in server process.".to_string()))?;

ctrlc::set_handler(move || shutdown_tx.shutdown())
.change_context_lazy(|| Error("failed to setup ctrl-c signal handle".to_string()))?;
.or_raise(|| Error("failed to setup ctrl-c signal handle".to_string()))?;

server.await_shutdown().await;
Ok(())
Expand All @@ -207,7 +204,7 @@ async fn run_gossip_proxy(
flatten_config.advertise_peer_addr.as_deref(),
)
.await
.change_context_lazy(make_error)?;
.or_raise(make_error)?;
let advertise_peer_addr = advertise_peer_addr.to_string();

let initial_peer_addrs = flatten_config
Expand All @@ -222,11 +219,11 @@ async fn run_gossip_proxy(
advertise_addr.clone(),
advertise_peer_addr.clone(),
)
.change_context_lazy(make_error)?
.or_raise(make_error)?
{
node.advance_incarnation();
node.persist(&node_file_path(&flatten_config.dir))
.change_context_lazy(make_error)?;
.or_raise(make_error)?;
node
} else {
let node = NodeInfo::init(
Expand All @@ -237,7 +234,7 @@ async fn run_gossip_proxy(
advertise_peer_addr,
);
node.persist(&node_file_path(&flatten_config.dir))
.change_context_lazy(make_error)?;
.or_raise(make_error)?;
node
};

Expand All @@ -251,7 +248,7 @@ async fn run_gossip_proxy(
.clone()
.start(gossip_rt, shutdown_rx, acceptor)
.await
.change_context_lazy(make_error)?;
.or_raise(make_error)?;

Ok((Proxy::new(gossip), futs))
}
31 changes: 31 additions & 0 deletions cmd/percas/src/styled.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2025 ScopeDB <contact@scopedb.io>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anstyle::AnsiColor;
use anstyle::Color;

pub fn styled() -> clap::builder::Styles {
let base = anstyle::Style::new();
let bold = base.bold();
let bold_underline = base.bold().underline();

clap::builder::Styles::styled()
.usage(bold_underline.fg_color(Some(Color::Ansi(AnsiColor::BrightGreen))))
.header(bold_underline.fg_color(Some(Color::Ansi(AnsiColor::BrightGreen))))
.valid(bold_underline.fg_color(Some(Color::Ansi(AnsiColor::Green))))
.literal(bold.fg_color(Some(Color::Ansi(AnsiColor::BrightCyan))))
.invalid(bold.fg_color(Some(Color::Ansi(AnsiColor::Red))))
.error(bold.fg_color(Some(Color::Ansi(AnsiColor::Red))))
.placeholder(base.fg_color(Some(Color::Ansi(AnsiColor::Cyan))))
}
2 changes: 1 addition & 1 deletion crates/cluster/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ release = false

[dependencies]
backon = { workspace = true }
error-stack = { workspace = true }
exn = { workspace = true }
fastimer = { workspace = true }
jiff = { workspace = true }
log = { workspace = true }
Expand Down
19 changes: 8 additions & 11 deletions crates/cluster/src/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use std::time::Duration;

use backon::ConstantBuilder;
use backon::Retryable;
use error_stack::Result;
use error_stack::ResultExt;
use error_stack::bail;
use exn::Result;
use exn::ResultExt;
use exn::bail;
use fastimer::MakeDelayExt;
use jiff::Timestamp;
use mea::shutdown::ShutdownRecv;
Expand Down Expand Up @@ -135,9 +135,7 @@ impl GossipState {
poem::Server::new_with_acceptor(acceptor)
.run_with_graceful_shutdown(route, signal, Some(Duration::from_secs(10)))
.await
.change_context_lazy(|| {
ClusterError::Internal("failed to run gossip proxy".to_string())
})
.or_raise(|| ClusterError::Internal("failed to run gossip proxy".to_string()))
})
};
wg.await;
Expand Down Expand Up @@ -398,20 +396,19 @@ impl Transport {
|| ClusterError::Transport(format!("failed to send message to {endpoint}"));

let url = Url::parse(&format!("http://{endpoint}"))
.change_context_lazy(make_error)?
.join("gossip")
.change_context_lazy(make_error)?;
.and_then(|url| url.join("gossip"))
.or_raise(make_error)?;

let resp = self
.client
.post(url)
.json(message)
.send()
.await
.change_context_lazy(make_error)?;
.or_raise(make_error)?;

if resp.status().is_success() {
resp.json().await.change_context_lazy(make_error)
resp.json().await.or_raise(make_error)
} else {
bail!(make_error())
}
Expand Down
Loading
Loading