Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration Reference

Every value on this page is read from the current source. The code wins when the two disagree. Builder-level options come from SimulationBuilder. World-level options (network and storage profiles) are drawn per seed by the runner or set on SimWorld directly in low-level tests.

SimulationBuilder

MethodDefaultPurpose
new()Start a builder.
processes(count, factory)Register one server group. count is usize or RangeInclusive<usize> (ProcessCount). The g-th group lives on 10.0.{g+1}.x. Duplicate group names panic.
cluster(LocalityConfig, factory)Register a group whose count comes from a sampled topology. The group may draw zero processes.
tags(&[(key, &[values])]) -> Result<Self>Round-robin tag dimensions over the last registered group.
workload(instance)One test driver instance. Not valid with exploration or check_determinism.
workload_factory(|| Box<dyn Workload>)A fresh driver per run.
workloads(WorkloadCount, |i| Box<dyn Workload>)Fixed(n) or Random(range) drivers per run.
enable_chaos([Chaos, ..])no chaosEnable chaos surfaces (table below).
chaos_duration(Duration)noneThe fault-generation window. Required by fault_factory. After it, enter_recovery_mode turns off every configuration-driven family and heals held partitions.
chaos_until_run_ends()offChaos ends when the last workload’s run() returns, chaos_duration its cap. An early run() stops no sibling, and check() runs on the live processes after the cutoff.
fault_factory(|| Box<dyn FaultInjector>)A custom injector per run. run() returns InvalidConfiguration without chaos_duration.
network_fault_mask(NetworkFaultMask)all()Remove network fault families after the per-seed draw.
storage_fault_mask(StorageFaultMask)all()Remove storage fault families after the per-seed draw.
replicated_storage_faults(ReplicatedFaults)noneBound storage damage to a tolerated set of failure domains.
swarm_operations()offDraw a per-seed subset of each workload’s operation alphabet.
link_latency(LinkLatencyConfig)noneLocality-aware link latency.
tcp_send_window_bytes(usize)64 KiBByte window per stream direction.
accept_backlog_capacity(usize)128Unaccepted connections per listener. Must be above 0.
invariant(impl Invariant)Run a cursor-based check after every step.
invariant_fn(name, |q, time_ms| ..)Closure form of invariant.
trace_level(LevelFilter)INFOCapture level for the timeline.
metrics_factory(..)One MetricsSource per node.
metric(MetricQueryPlan)A metric query reported per campaign.
set_iterations(n)IterationControl::FixedCount(n).
until_coverage_stable(plateau_seeds, max_iterations)10, 1000IterationControl::UntilCoverageStable. This is the default.
set_debug_seeds(Vec<u64>)Pin seeds. They run first.
run_time_budget(Duration)1 simulated hourA run past this budget is reported as a stall.
replay_timeline(seed, recipe)One seed, one iteration, the recipe installed as RNG breakpoints.
enable_exploration(ExplorationConfig)offMultiverse exploration. Needs factory workloads. Panics on a zero bound.
check_determinism()offRun every seed twice and fail on a diverging draw. Needs factory workloads.
run() -> SimulationResult<SimulationReport>Run the campaign.

There is no builder method that takes a NetworkConfiguration or StorageConfiguration. The runner draws both per seed. Low-level tests set them on SimWorld with new_with_network_config, set_network_config, set_storage_config and set_process_storage_config.

Enums

EnumVariants
IterationControlFixedCount(usize), UntilCoverageStable { plateau_seeds, max_iterations }
ProcessCountFixed(usize), Range(RangeInclusive<usize>)
WorkloadCountFixed(usize), Random(Range<usize>)
ChaosModeRandom (every family on, rates drawn per seed), Swarm (a per-seed subset of families)
ChaosNetwork(ChaosMode), Storage(ChaosMode), Attrition { config, mode }, Outage { config, mode }, BuggifyKnobs, Cpu(ChaosMode), GrayFailure { config, mode }

Without Chaos::Network, the network is not fault-free. It uses NetworkConfiguration::default(), whose ChaosConfiguration::default() keeps random closes, clock drift, buggified delays and probabilistic connect failures on, as FoundationDB does. Without Chaos::Storage, storage uses StorageConfiguration::default(), where every fault probability is 0.

Draw Order

Every random decision is a counted draw on the one simulation stream. The runner draws in this order per seed:

  1. Network profile and storage profile, before the reset that starts the RNG count. A replay breakpoint can never land on them.
  2. The world reset.
  3. Swarm operation masks (when enabled).
  4. Attrition, outage, replicated faults, CPU model and gray-failure regimes.
  5. The run itself.

Adding a draw anywhere shifts every later seed. That is intended. The same seed must still replay identically.

Attrition

Attrition has no Default. Set every field:

FieldTypeDefault when NoneMeaning
max_deadusizeSimultaneously dead processes among this injector’s victims.
prob_gracefulf64Weight for RebootKind::Graceful.
prob_crashf64Weight for RebootKind::Crash.
prob_wipef64Weight for RebootKind::CrashAndWipe.
recovery_delay_msOption<Range<usize>>1000..10000Restart delay after a kill.
grace_period_msOption<Range<usize>>2000..5000Time between token cancel and force kill.
scopeAttritionScopePerProcessPerProcess, PerMachine, PerZone, PerDatacenter.
victimsAttritionVictimsAnyAny, Group(String) via ::group(name), Tagged { key, value } via ::tagged(key, value).

The weights are relative. Attrition::swarm_for_seed() (used by ChaosMode::Swarm) draws 6 times: max_dead becomes 0 with probability 0.5, each weight is masked with probability 0.5, the recovery delay is scaled between 50% and 200%, and the scope is drawn among the scopes the topology supports.

Outage

Outage::groups(["acceptors", ..]) builds the default regime:

FieldDefaultMeaning
groupsas givenProcess groups that lose power together.
probability1.0Chance a seed has the outage at all.
start0s..10sWhen it strikes, from the start of the chaos window. A draw past the window means no outage.
down1s..10sHow long each victim stays down.
stragglerNoneOne victim that stays down longer. Must start at or after down’s end.

At most one outage per run. Under Swarm the outage is dropped on half the seeds and its straggler on half the rest. A workload publishes OutageVeto::new(|victims: &[String]| bool) through ctx.state() under OUTAGE_VETO_KEY ("moonpool:outage-veto") to hold an outage. The simulator retries every VETO_RETRY (1 ms). The landed outage is published as OutageLanded { at, victims, down, straggler } under OUTAGE_STATE_KEY ("moonpool.outage").

Gray Failure

GrayFailure::new(max_slow):

FieldDefaultMeaning
victimsAttritionVictims::AnyWhich processes may be slowed.
max_slowas givenMachines slow at the same time. Use the tolerated loss f.
window0.3..=1.0Slow window as a fraction of the chaos window.
cpu10..=1000CPU slowdown factor range.
disk5..=100Disk latency factor range.
network2..=20Network latency factor range.
kindsGrayKinds::ALLcpu, disk, network flags. Swarm masks each per seed.

SimContext::slowness(ip) and FaultContext::slowness(ip) return the current Slowness { cpu, disk, network }. Slowness::HEALTHY is all ones.

CPU Model

Chaos::Cpu(mode) installs a CpuModel per seed:

FieldDrawn fromMeaning
poll_costPOLL_COST_NS = 500..5001 nsCost of one poll of one task.
sent_byte_cost_psBYTE_COST_PS = 500..5001 psCost per byte sent.
written_byte_cost_psBYTE_COST_PS = 500..5001 psCost per byte written to disk.

CpuModel::random_for_seed() draws 3 times. CpuModel::swarm_for_seed() -> Option<CpuModel> draws one coin (0.5) and then the three costs. cpu_charge(Duration) adds explicit CPU time from application code. SimWorld::set_cpu_model installs a model by hand.

Locality

LocalityConfig::new(datacenters, zones_per_datacenter, machines_per_zone, processes_per_machine). Each argument is a usize or a RangeInclusive<usize> sampled per seed. DomainLevel is Datacenter, Zone or Machine. LinkClass is SameMachine, SameZone, SameDatacenter or CrossDatacenter.

LinkLatencyConfig::default():

Link classLatency
same_machine10 µs to 50 µs
same_zone100 µs to 500 µs
same_datacenter500 µs to 2 ms
cross_datacenter20 ms to 80 ms

NetworkConfiguration

FieldDefaultfast_local()
bind_latencyUniform 50 µs to 150 µs1 µs to 10 µs
accept_latencyUniform 1 ms to 6 ms1 µs to 10 µs
connect_latencyUniform 1 ms to 11 ms1 µs to 10 µs
write_latencyUniform 100 µs to 600 µs1 µs to 10 µs
link_latencyNoneNone
tcp_send_window_bytes65536 (DEFAULT_TCP_SEND_WINDOW_BYTES)same
accept_backlog_capacity128 (DEFAULT_ACCEPT_BACKLOG_CAPACITY)same
chaosChaosConfiguration::default()ChaosConfiguration::disabled()

NetworkConfiguration::random_for_seed() and swarm_for_seed() draw the chaos block (below). disable_fault_injection() is what recovery mode calls.

LatencyDistribution variants: Uniform { start, end }, Exponential { min, mean }, Bimodal { fast_range, slow_range, slow_probability }. sample_latency and sample_duration draw from them.

ChaosConfiguration (network)

Fielddefault()random_for_seed() range
clog_rate0.00.05 to 1 clogs per simulated second
clog_duration100 ms to 300 msstart 50 to 300 ms, end 100 to 500 ms
partition_rate0.00.05 to 0.5 partitions per simulated second
partition_duration200 ms to 2 sstart 100 ms to 1 s, end 500 ms to 3 s
bit_flip_probability0.00.00001 to 0.0002
bit_flip_min_bits11
bit_flip_max_bits3232
bit_flip_cooldown00 to 100 ms
partial_write_max_bytes1000100 to 2000
partial_read_max_bytes1000100 to 2000
random_close_probability0.000010.000001 to 0.0001
random_close_cooldown5 s1 s to 10 s
random_close_explicit_ratio0.30.20 to 0.40
black_hole_probability0.00.000001 to 0.0001
black_hole_cooldown5 s1 s to 10 s
clock_drift_enabledtruetrue
clock_drift_max100 ms50 ms to 150 ms
buggified_delay_enabledtruetrue
buggified_delay_max100 ms50 ms to 150 ms
buggified_delay_probability0.250.20 to 0.30
connect_failure_modeProbabilisticone of Disabled, AlwaysFail, Probabilistic
connect_failure_probability0.50.40 to 0.60
max_pair_latency0 to 0 (off)0 to 0..100 ms
partition_strategyRandomone of the 7 strategies

disabled() zeroes every probability and turns every flag off. swarm_for_seed() draws random_for_seed() then 9 coins (0.5 each) that keep or drop clog, partition, bit flip, random close, connect failure, clock drift, buggified delay, pair latency and black hole. apply_buggify_knobs() (under Chaos::BuggifyKnobs) spikes clog to 2..5 per second, partition to 0.5..2 per second, random close to 0.01..0.1, black hole to 0.01..0.1, and bit flip to 0.001..0.01. It spikes a family only when it was already above 0, so a family the swarm turned off stays off.

PartitionStrategy: Random, UniformSize, IsolateSingle, IsolateZone, IsolateDatacenter, AsymmetricSend, AsymmetricRecv. ConnectFailureMode: Disabled, AlwaysFail, Probabilistic.

StorageConfiguration

Fielddefault()random_for_seed() rangefast_local()
iops25 00010 000 to 100 0001 000 000
bandwidth (bytes/s)150 000 00050 MB/s to 500 MB/s1 GB/s
read_latency50 µs to 200 µs1 µs
write_latency100 µs to 500 µs1 µs
sync_latency1 ms to 5 ms1 µs
read_corruption_probability0.00 to 0.0010
write_corruption_probability0.00 to 0.0010
read_eio_probability0.00 to 0.0010
write_eio_probability0.00 to 0.0010
clean_crash_probability0.1
correlated_rollback_probability0.25
correlated_rollback_max_run8
crash_lost_probability0.00 to 0.10
crash_latent_fault_probability0.00 to 0.050
shorn_write_probability0.00
length_survives_crash_probability0.5
garbage_fill_probability1.00.5
barrier_violation_probability0.00
misdirect_write_probability0.00 to 0.00010
misdirect_read_probability0.00 to 0.00010
phantom_write_probability0.00 to 0.00020
sync_failure_probability0.00 to 0.00050
direct_io_alignment4096
direct_io_supportedtrue
unsynced_dir_entry_loss_probability0.00 to 0.0050
short_transfer_probability0.00 to 0.0020
disk_stall_probability0.00 to 0.0010
disk_stall_duration050 ms to 500 ms
disk_throttle_probability0.00 to 0.0010
disk_throttle_duration0500 ms to 5 s
disk_throttle_iops_multiplier1.02 to 20
disk_throttle_bandwidth_multiplier1.02 to 20
disk_failure_probability0.00 to 0.00010
dropped_mutation_discard_probability0.00 to 0.490

swarm_for_seed() draws random_for_seed() then 15 coins over the families. apply_buggify_knobs() spikes iops to 100..5000, bandwidth to 1 MB/s..20 MB/s, sync failure to 0.05..0.2, disk stall to 0.1..0.5 with 100 ms to 500 ms episodes, throttle to 0.1..0.5 with 1 s to 5 s episodes, and disk failure to 0.001..0.01. disable_fault_injection() zeroes every family, including barrier violation. Sectors are SECTOR_SIZE = 512 bytes.

Aiming Storage Faults

TypeAPI
StorageEligibilityMaskArc<dyn Fn(&str, u64) -> bool> over (path, sector). SimWorld::set_storage_eligibility_mask, clear_storage_eligibility_mask.
FaultFocusFaultFocus::new().background(w).spot(path, bytes, w).layout(regions, |r| w). weight(path, sector) is the heaviest spot or the background. SimWorld::set_fault_focus, clear_fault_focus, SimStorageProvider::focus_faults.
LayoutRegion{ path, bytes: Range<u64>, kind: &'static str, stripe: Option<u64>, shard: Option<String> } from moonpool_core. Published with SimWorld::publish_layout.
ReplicatedFaultsReplicatedFaults::new(DomainLevel).tolerance(n).group("name"). The pattern per seed is a FaultPattern: Minority { domains }, Striped { domains, local }, Rolling { .. }, Spared.

ExplorationConfig

FieldDefaultMeaning
workers0Forked workers. 0 runs in-process and deterministic.
max_runs_per_seed512Ceiling on timelines per root seed.
branching_factor4Children per productive run.
max_frontier1024Queued jobs.
max_recipe_len64Depth in replay segments.

validate() rejects a zero in any bound except workers. The worker wall-clock ceiling is DEFAULT_WORKER_TIMEOUT = 5 minutes (Explorer::set_worker_timeout).

Buggify

ItemValue
buggify_init(activation_prob)The runner calls buggify_init(0.5) per run: each site is active on half the seeds.
buggify!()Fires with probability 0.25 at an active site.
buggify_with_prob!(p)Fires with probability p at an active site.
buggify_fault_with_prob!(p)Same, but silent in recovery mode.
buggify_named!("label", p)Same, under a label that set_activation(label, bool) controls.
buggify_pick!(p, n) -> Option<usize>An index below n, or None.
buggify_range!(p, range) -> Option<u64>A value in range, or None.
buggify_knob!(default, lo..hi)moonpool-sim only. The value in lo..hi with probability 0.25 at an active site, else default.
hint!("label"), hint!("label", p)A fault moment. Default point probability 0.05. A no-op in production.

See Fault Reference for what each fault does.