Skip to content

Commit

Permalink
refactor: expose configs to docs
Browse files Browse the repository at this point in the history
  • Loading branch information
loyd committed Jul 12, 2024
1 parent 081cf50 commit 778241f
Show file tree
Hide file tree
Showing 25 changed files with 391 additions and 89 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- errors: add `From<SendError> for TrySendError` and `SendError::{into_inner,map}` methods.
- core/config: add the `system.mailbox.capacity` parameter to set the mailbox capacity.
- core/context: add `Context::set_mailbox_capacity()`.
- docs: expose all configs to the rustdoc.

### Changed
- **BREAKING** core/mailbox: default capacity is `100` now.
Expand Down
1 change: 1 addition & 0 deletions elfo-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ humantime-serde = "1"
elfo-utils = { version = "0.2.5", path = "../elfo-utils", features = ["test-util"] }

tokio = { workspace = true, features = ["full"] }
toml.workspace = true
anyhow = "1.0.40"
proptest = "1.4.0"

Expand Down
2 changes: 1 addition & 1 deletion elfo-core/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
envelope::Envelope,
errors::{SendError, TrySendError},
group::TerminationPolicy,
mailbox::{Mailbox, MailboxConfig, RecvResult},
mailbox::{config::MailboxConfig, Mailbox, RecvResult},
messages::{ActorStatusReport, Terminate},
msg,
request_table::RequestTable,
Expand Down
96 changes: 88 additions & 8 deletions elfo-core/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Contains useful utilities for working with configuration.
//!
//! Also contains [`system`] to describe system configuration.
use std::{
any::{Any, TypeId},
fmt, mem,
Expand All @@ -11,13 +15,34 @@ use serde_value::{Value, ValueDeserializer};

use crate::{local::Local, panic};

/// Represents any user-defined config.
///
/// It's implemented automatically for any `Deserialize + Send + Sync + Debug`.
pub trait Config: for<'de> Deserialize<'de> + Send + Sync + fmt::Debug + 'static {}
impl<C> Config for C where C: for<'de> Deserialize<'de> + Send + Sync + fmt::Debug + 'static {}

assert_impl_all!((): Config);

// === AnyConfig ===

/// Holds user-defined config.
///
/// Usually not created directly outside tests sending [`ValidateConfig`] or
/// [`UpdateConfig`] messages.
///
/// [`ValidateConfig`]: crate::messages::ValidateConfig
/// [`UpdateConfig`]: crate::messages::UpdateConfig
///
/// # Example
/// In tests it can be used in the following way:
/// ```
/// # use serde::Deserialize;
/// # use toml::toml;
/// # use elfo_core::config::AnyConfig;
/// AnyConfig::deserialize(toml! {
/// some_param = 10
/// });
/// ```
#[derive(Clone)]
pub struct AnyConfig {
raw: Arc<Value>,
Expand Down Expand Up @@ -164,18 +189,73 @@ impl<'de> Deserializer<'de> for AnyConfig {

// === SystemConfig ===

#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub(crate) struct SystemConfig {
pub(crate) mailbox: crate::mailbox::MailboxConfig,
pub(crate) logging: crate::logging::LoggingConfig,
pub(crate) dumping: crate::dumping::DumpingConfig,
pub(crate) telemetry: crate::telemetry::TelemetryConfig,
pub(crate) restart_policy: crate::restarting::RestartPolicyConfig,
pub mod system {
//! System (`system.*` in TOML) configuration. [Config].
//!
//! Note: all types here are exported only for documentation purposes
//! and are not subject to stable guarantees. However, the config
//! structure (usually encoded in TOML) follows stable guarantees.
//!
//! [Config]: SystemConfig
use super::*;

pub use crate::{
dumping::config as dumping, logging::config as logging, mailbox::config as mailbox,
restarting::config as restart_policy, telemetry::config as telemetry,
};

/// The `system.*` section in configs.
///
/// # Example
/// ```toml
/// [some_group]
/// system.mailbox.capacity = 1000
/// system.logging.max_level = "Warn"
/// system.dumping.max_rate = 10_000
/// system.telemetry.per_actor_key = true
/// system.restart_policy.when = "Never"
/// ```
#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct SystemConfig {
/// Mailbox configuration.
pub mailbox: mailbox::MailboxConfig,
/// Logging configuration.
pub logging: logging::LoggingConfig,
/// Dumping configuration.
pub dumping: dumping::DumpingConfig,
/// Telemetry configuration.
pub telemetry: telemetry::TelemetryConfig,
/// Restarting configuration.
pub restart_policy: restart_policy::RestartPolicyConfig,
}
}

pub(crate) use system::SystemConfig;

// === Secret ===

/// A secret value that is not printed in logs or debug output.
/// So, it's useful for storing sensitive data like credentials.
///
/// * `Debug` and `Display` instances prints `<secret>` instead of real value.
/// * `Deserialize` expects a real value.
/// * `Serialize` depends on the current [serde mode]:
/// * In the `Network` mode it's serialized as the real value.
/// * In the `Dumping` and `Normal` modes it's serialized as `"<secret>"`.
///
/// [serde mode]: crate::scope::with_serde_mode
///
/// # Example
/// ```
/// # use serde::Deserialize;
/// # use elfo_core::config::Secret;
/// #[derive(Deserialize)]
/// struct MyConfig {
/// credentials: Secret<String>,
/// }
/// ```
#[derive(Clone, Copy, PartialEq, Eq, Default, From)]
pub struct Secret<T>(T);

Expand Down
25 changes: 22 additions & 3 deletions elfo-core/src/dumping/config.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
//! [Config].
//!
//! [Config]: DumpingConfig
use serde::Deserialize;

/// Dumping configuration.
///
/// # Example
/// ```toml
/// [some_group]
/// system.dumping.disabled = false
/// system.dumping.max_rate = 1_000
/// ```
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub(crate) struct DumpingConfig {
pub(crate) disabled: bool,
pub(crate) max_rate: u64,
pub struct DumpingConfig {
/// Whether dumping is disabled.
///
/// `false` by default.
pub disabled: bool,
/// Maximum rate of dumping.
/// Exceeding this rate will cause messages to not be dumped.
///
/// `100_000` by default.
pub max_rate: u64,
// TODO: per class overrides.
}

Expand Down
5 changes: 2 additions & 3 deletions elfo-core/src/dumping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ pub(crate) use self::{
sequence_no::SequenceNo,
};

pub(crate) use self::config::DumpingConfig;

#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
#[stability::unstable]
pub const INTERNAL_CLASS: &str = "internal";

mod config;
pub mod config;

mod control;
mod dump;
mod dumper;
Expand Down
24 changes: 21 additions & 3 deletions elfo-core/src/logging/config.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
//! [Config].
//!
//! [Config]: LoggingConfig
use serde::{Deserialize, Deserializer};
use tracing::level_filters::LevelFilter;

/// Logging configuration.
///
/// # Example
/// ```toml
/// [some_group]
/// system.logging.max_level = "Warn"
/// system.logging.max_rate_per_level = 1_000
/// ```
#[derive(Debug, Deserialize)]
#[serde(default)]
pub(crate) struct LoggingConfig {
pub struct LoggingConfig {
/// Maximum level of logging.
///
/// `Info` by default.
#[serde(deserialize_with = "deserialize_level_filter")]
pub(crate) max_level: LevelFilter,
pub(crate) max_rate_per_level: u64,
pub max_level: LevelFilter,
/// Maximum rate of logging per level.
///
/// `1_000` by default.
pub max_rate_per_level: u64,
}

impl Default for LoggingConfig {
Expand Down
3 changes: 1 addition & 2 deletions elfo-core/src/logging/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub(crate) use self::config::LoggingConfig;
pub mod config;

mod config;
mod control;

// TODO: use `stability` instead.
Expand Down
38 changes: 29 additions & 9 deletions elfo-core/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,35 @@ use crate::{

// === MailboxConfig ===

#[derive(Debug, PartialEq, serde::Deserialize)]
#[serde(default)]
pub(crate) struct MailboxConfig {
pub(crate) capacity: usize,
}
pub mod config {
//! [Config]
//!
//! [Config]: MailboxConfig
/// Mailbox configuration.
///
/// # Example
/// ```toml
/// [some_group]
/// system.mailbox.capacity = 1000
/// ```
#[derive(Debug, PartialEq, serde::Deserialize)]
#[serde(default)]
pub struct MailboxConfig {
/// The maximum number of messages that can be stored in the mailbox.
///
/// Can be overriden by actor using [`Context::set_mailbox_capacity()`].
///
/// `100` by default.
///
/// [`Context::set_mailbox_capacity()`]: crate::Context::set_mailbox_capacity
pub capacity: usize,
}

impl Default for MailboxConfig {
fn default() -> Self {
Self { capacity: 100 }
impl Default for MailboxConfig {
fn default() -> Self {
Self { capacity: 100 }
}
}
}

Expand Down Expand Up @@ -118,7 +138,7 @@ struct Control {
}

impl Mailbox {
pub(crate) fn new(config: &MailboxConfig) -> Self {
pub(crate) fn new(config: &config::MailboxConfig) -> Self {
let capacity = clamp_capacity(config.capacity);

Self {
Expand Down
46 changes: 43 additions & 3 deletions elfo-core/src/restarting/config.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,69 @@
//! [Config].
//!
//! [Config]: RestartPolicyConfig
use std::{num::NonZeroU64, time::Duration};

use serde::Deserialize;

use crate::restarting::restart_policy::{RestartParams, RestartPolicy};

/// Restart policy configuration, `Never` by default.
///
/// Overrides [`ActorGroup::restart_policy()`].
/// Can be overriden by actor using [`Context::set_restart_policy()`].
///
/// See [The Actoromicon] for details.
///
/// # Example
/// ```toml
/// [some_group]
/// system.restart_policy.when = "OnFailure"
/// system.restart_policy.min_backoff = "5s"
/// system.restart_policy.max_backoff = "30s"
/// ```
///
/// [`ActorGroup::restart_policy()`]: crate::ActorGroup::restart_policy
/// [`Context::set_restart_policy()`]: crate::Context::set_restart_policy
/// [The Actoromicon]: https://actoromicon.rs/ch04-02-supervision.html#restart
#[derive(Debug, Clone, Default, Deserialize)]
pub(crate) struct RestartPolicyConfig(Option<WhenConfig>);
pub struct RestartPolicyConfig(pub Option<WhenConfig>);

/// Restart policies.
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "when")]
enum WhenConfig {
pub enum WhenConfig {
/// Restart both on failures and terminations.
Always(RestartParamsConfig),
/// Restart only on failures.
OnFailure(RestartParamsConfig),
/// Never restart actors.
Never,
}

/// Restart policy parameters.
#[derive(Debug, Clone, Deserialize)]
struct RestartParamsConfig {
pub struct RestartParamsConfig {
/// Minimal restart time limit.
#[serde(with = "humantime_serde")]
min_backoff: Duration,
/// Maximum restart time limit.
#[serde(with = "humantime_serde")]
max_backoff: Duration,
/// The duration of an actor's lifecycle sufficient to deem the actor
/// healthy.
///
/// The default value is `min_backoff`.
#[serde(with = "humantime_serde", default)]
auto_reset: Option<Duration>,
/// The limit on retry attempts, after which the actor stops attempts to
/// restart.
///
/// Unlimited by default.
max_retries: Option<NonZeroU64>,
/// The value to multiply the current delay with for each retry attempt.
///
/// Default value is 2.0.
factor: Option<f64>,
}

Expand Down
5 changes: 3 additions & 2 deletions elfo-core/src/restarting/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod config;

mod backoff;
mod config;
mod restart_policy;

pub(crate) use self::{backoff::RestartBackoff, config::RestartPolicyConfig};
pub(crate) use self::backoff::RestartBackoff;
pub use restart_policy::{RestartParams, RestartPolicy};
2 changes: 1 addition & 1 deletion elfo-core/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
dumping::DumpingControl,
logging::_priv::LoggingControl,
permissions::{AtomicPermissions, Permissions},
telemetry::TelemetryConfig,
telemetry::config::TelemetryConfig,
tracing::TraceId,
Addr,
};
Expand Down
Loading

0 comments on commit 778241f

Please sign in to comment.