Skip to main content

Redex

Struct Redex 

Source
pub struct Redex { /* private fields */ }
Expand description

Manager for a set of RedEX files bound to channel names.

Implementations§

Source§

impl Redex

Source

pub fn new() -> Redex

Create a manager without auth enforcement. Suitable for single-process tests and local workloads.

Source

pub fn with_auth(guard: Arc<AuthGuard>, origin_hash: u64) -> Redex

Create a manager that rejects open_file unless the (origin_hash, channel) pair has been authorized by guard via AuthGuard::allow_channel. Uses the exact 64-bit channel identity, not the 16-bit wire hash — see the module docs for rationale.

Source

pub fn with_persistent_dir(self, dir: impl Into<PathBuf>) -> Redex

Set the base directory for disk-backed (persistent: true) files. All files opened with persistent: true use <dir>/<channel_path>/{idx,dat} for durability.

Source

pub fn enable_replication(&self, mesh: Arc<MeshNode>)

Install replication wiring rooted at mesh. Constructs a fresh RedexReplicationRouter + ReplicationMetricsRegistry and registers the router on the mesh for SUBPROTOCOL_REDEX inbound dispatch. Idempotent — repeated calls return without disturbing the existing router (the second installation would orphan every per-channel runtime registered under the first).

After this returns, Self::open_file with a RedexFileConfig::replication of Some(cfg) spawns a per-channel runtime instead of producing the typed error.

Source

pub fn enable_greedy_dataforts( self: &Arc<Redex>, mesh: Arc<MeshNode>, config: GreedyConfig, local_caps: Arc<CapabilitySet>, intent_registry: IntentRegistry, ) -> Result<(), GreedyConfigError>

Install greedy-LRU wiring rooted at mesh. Validates the supplied super::super::dataforts::GreedyConfig, builds a super::super::dataforts::GreedyRuntime that opens per-channel cache files against this manager + announces chains via the mesh’s ChainTagSink impl, and installs the runtime as the mesh’s greedy observer.

Idempotent — a second call with greedy already enabled returns Ok without rebuilding (caller can layer disable_greedy_dataforts + enable_greedy_dataforts to reconfigure).

Returns Err(GreedyConfigError) for invalid configs — numeric bounds + bandwidth-fraction range. The runtime is never installed on an invalid config so operators see the typed error before observing any cache writes.

local_caps snapshots the node’s advertised capability set at install time so the intent / colocation admission gates have something to evaluate against. Refresh via Self::greedy_runtime + set_local_caps after each MeshNode::announce_capabilities.

Source

pub fn enable_gravity_for_greedy( &self, mesh: Arc<MeshNode>, policy: DataGravityPolicy, tick_interval: Duration, ) -> Result<(), DataGravityPolicyError>

Enable data-gravity heat-counter emission on the already- installed greedy runtime. Validates the supplied policy, installs it on the runtime, and spawns a tokio task that fires gravity_tick().await on tick_interval cadence.

Requires enable_greedy_dataforts to have been called first — without an installed greedy runtime the heat counter has nothing to read from. Returns Err(GreedyConfigError::*) if greedy isn’t enabled or the policy fails validation (range / non-finite checks).

Idempotent — a second call replaces the prior policy + restarts the tick task. The heat registry resets on each re-enable so the new policy starts from a clean slate.

mesh is consumed for its super::super::dataforts::HeatSink impl (announce_heat / withdraw_heat).

Source

pub fn disable_gravity_for_greedy(&self)

Disable data-gravity emission. Stops the tick task, clears the heat registry, and leaves greedy itself running. Idempotent — no-op when gravity isn’t enabled.

Source

pub fn greedy_runtime(&self) -> Option<Arc<GreedyRuntime>>

Borrow the installed greedy runtime, if any. Cheap clone of the Arc — callers refresh local caps via runtime.set_local_caps after every announce.

Source

pub fn disable_greedy_dataforts(&self)

Uninstall the greedy wiring. Idempotent — None if greedy wasn’t enabled.

Source

pub fn greedy_cache_for(&self, channel: &ChannelName) -> Option<RedexFile>

Operator-facing read-path lookup: if greedy is holding a cached copy of channel, return the cache’s RedexFile so the caller can tail / read_range against it.

The cache file is keyed under a synthesized name (dataforts/greedy/<channel_hash_hex>) per super::super::dataforts::synthesize_cache_channel_name; callers pass the real channel name and this method does the synthesis internally. On a cache hit, this also bumps the read-recency LRU position and the dataforts_greedy_serve_count_total metric — same shape as the substrate’s “served from cache” accounting.

Returns None when greedy isn’t enabled OR the channel isn’t in the cache. Callers fall back to whatever they were doing before greedy (typically the substrate’s own find_chain_holders + network fetch).

Source

pub fn replication_runtime_count(&self) -> usize

Cumulative count of per-channel replication runtimes currently registered on this manager. 0 when replication is not enabled. Exposed for tests + operator observability.

Source

pub fn replication_coordinator_for( &self, name: &ChannelName, ) -> Option<Arc<ReplicationCoordinator>>

The per-channel ReplicationCoordinator for name, if a replicated runtime was spawned for it. None when:

  • replication is not enabled on this manager, OR
  • no file is open at name, OR
  • the file at name was opened without RedexFileConfig::replication.

Exposed for operator inspection (coordinator.role(), coordinator.metrics()) and test-driven role transitions (coordinator.transition_to(target, signal)). Production drives transitions through the placement filter (Phase F) + election cycle; the surface is here so operators can also force a transition for recovery / debugging.

Source

pub fn replication_metrics_snapshot(&self) -> Option<ReplicationMetricsSnapshot>

Read-only snapshot of the per-channel replication metrics — the seven counter / gauge shapes from CONFIG_REPLICATION.md: *_lag_seconds, *_sync_bytes_total, *_leader_changes_total, *_under_capacity_total, *_skip_ahead_total, *_election_thrash_total, *_witness_withdrawals_total.

None when replication isn’t enabled on this manager.

Cheap — copies atomic counters into plain data. Suitable for a per-scrape Prometheus pull. See ReplicationMetricsSnapshot::prometheus_text for the rendered output; Self::replication_prometheus_text is the one-call wrapper.

Source

pub fn replication_prometheus_text(&self) -> String

Convenience wrapper — render the replication metrics snapshot as Prometheus text. Returns the empty string when replication isn’t enabled (rather than None) so the call site can pipe it straight into an HTTP body without an unwrap_or_default.

Source

pub fn replication_status_snapshot( &self, ) -> Option<Vec<ReplicationChannelStatus>>

Per-channel replication status snapshot — the richer view the Phase H MeshDaemon::snapshot integration point was supposed to surface. For every replicated channel registered on this manager, returns the current ReplicaRole, tail_seq, and channel_name. Pair with Self::replication_metrics_snapshot for the full observability picture (status here + atomic counters there).

None when replication isn’t enabled. Empty vector when replication is enabled but no channels have been opened.

Source

pub fn open_file( &self, name: &ChannelName, config: RedexFileConfig, ) -> Result<RedexFile, RedexError>

Open (create if absent) a RedEX file bound to name.

Re-opening an existing name returns the existing handle. The config argument is honored only on first open; subsequent opens ignore it and return the live file.

With persistent: true, the manager must have been configured via with_persistent_dir (feature redex-disk) — otherwise open_file returns a RedexError::Channel that describes the missing base dir.

Source

pub fn get_file(&self, name: &ChannelName) -> Option<RedexFile>

Look up an already-opened file.

Source

pub fn close_file(&self, name: &ChannelName) -> Result<(), RedexError>

Close and remove a file. Outstanding tail streams receive RedexError::Closed. No-op if no file is open under name. If the channel had a replication runtime spawned, the runtime is unregistered from the router and signaled to shut down; the runtime exits on its next inbox poll after observing Inbound::Shutdown.

Close the file (as Self::close_file) AND unlink any persistent on-disk segment for the channel. Idempotent: a channel that has no persistent dir or is unknown to the manager returns Ok. Used by the blob GC sweep so a swept chunk doesn’t accumulate as an orphaned segment directory on with_persistent(true) deployments.

Holds the dashmap entry write guard for the channel name across the close-then-unlink sequence. Pre-fix the entry was dropped between close_file (which removes from the map) and remove_dir_all; a concurrent open_file for the same name landed a fresh entry in the gap, then the unlink blew away the new segment dir and the next append hit ENOENT. Holding the entry guard blocks any concurrent open_file on the same name until both phases complete.

Source

pub fn open_files(&self) -> Vec<RedexFile>

Snapshot list of currently open files. Cheap clone.

Source

pub fn sweep_retention(&self)

Run retention on every open file. Typically called on a heartbeat tick by the owning runtime.

Trait Implementations§

Source§

impl Debug for Redex

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Redex

Source§

fn default() -> Redex

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Redex

§

impl !RefUnwindSafe for Redex

§

impl !UnwindSafe for Redex

§

impl Send for Redex

§

impl Sync for Redex

§

impl Unpin for Redex

§

impl UnsafeUnpin for Redex

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more