Skip to main content

Crate krabka_units

Crate krabka_units 

Source
Expand description

Dimensioned quantities for Krabka.

A broker is full of numbers that mean nothing on their own. max_bytes, session_timeout_ms, and throttle_bytes_per_sec are all integers, so a function that takes two of them accepts them transposed and still compiles. A value that crosses a module boundary in the wrong unit is a runtime bug and not a compile error: seconds where milliseconds were expected, or bits where bytes were expected. A unit written into the name shows the intent. It does not enforce it.

This crate gives those magnitudes real types, built on uom: ByteSize, ByteRate, Time, Frequency, and Ratio. Each one is a uom quantity, so unit conversion is a method call and not a hand-written multiplication. uom also checks arithmetic across dimensions:

use krabka_units::prelude::*;

let batch = mebibytes(8);
let window = secs(2);
let rate: ByteRate = (batch / window).into();
assert_eq!(rate.bytes_per_sec_i64(), 4 * 1024 * 1024);

§Magnitudes, not instants

These types model extents: how many bytes, how long, how fast. They do not model points. A log offset, a leader epoch, or an epoch-milliseconds timestamp is an identifier or a coordinate and not a dimensioned magnitude, so it stays a newtype in krabka-ids. An absolute nanosecond timestamp also cannot round-trip through f64 seconds, which is a second reason why instants do not belong here. The next section gives the detail.

§Storage type

Every quantity stores f64 in SI base units: bytes, seconds, bytes/second, and hertz. One storage type across all five dimensions is what makes cross-dimension arithmetic usable, because uom only combines quantities that share it. f64 is also the only choice wide enough for both ends of the range the broker needs. uom’s integer quantities store base units, so they cannot represent a sub-second duration at all.

f64 represents every integer below 2^53 exactly, which covers byte counts up to 8 PiB and durations up to 285 years of milliseconds, so conversions back to wire integers are exact over the whole range Kafka can express. Absolute nanosecond timestamps (~1.8 × 10^18) are the exception, and are excluded above.

§Wire boundary

The generated Kafka codec (krabka-protocol’s generated module) stays raw integers, because it must be byte-exact. Convert a value when it enters or leaves the hand-written domain layer. Use the extension traits in convert:

use krabka_units::prelude::*;

// Decoding a request: raw `int32` milliseconds in, `Time` out.
let timeout = Time::from_millis(30_000);
assert_eq!(timeout, secs(30));

// Encoding a response: `Time` in, raw `int32` milliseconds out.
assert_eq!(timeout.millis_i32(), 30_000);

§Configuration

parse reads the human forms operators write (512MiB, 30s, 10MiB/s) and fmt writes them back. serde_units wires both into #[serde(with = ...)], so a config struct holds quantities and not integers.

See the code style guide’s “Newtypes for Domain Values” section for the sibling rule covering identifiers.

Re-exports§

pub use uom;

Modules§

convert
Conversions between quantities and the raw numbers at the edges of the system.
fmt
Rendering a quantity in the form an operator wrote it.
parse
Parsing the human forms of a quantity: 512MiB, 30s, 10MiB/s, 25%.
prelude
Everything needed to name, build, and unwrap a quantity.
serde_units
serde adapters, so a config or API struct can hold quantities.

Functions§

byte_rate
A byte rate given as a byte count over a time extent, without an intermediate division at the call site.
bytes
n bytes.
bytes_per_sec
n bytes per second.
days
n days.
fraction
A dimensionless fraction, where 1.0 is the whole.
gibibytes
n gibibytes (1 GiB = 1024 MiB).
gibibytes_per_sec
n gibibytes per second.
hours
n hours.
kibibytes
n kibibytes (1 KiB = 1024 B).
kibibytes_per_sec
n kibibytes per second.
mebibytes
n mebibytes (1 MiB = 1024 KiB).
mebibytes_per_sec
n mebibytes per second.
micros
n microseconds.
millis
n milliseconds.
minutes
n minutes.
nanos
n nanoseconds.
per_sec
n events per second.
percent
n percent, as a dimensionless Ratio (percent(25) == fraction(0.25)).
secs
n seconds.

Type Aliases§

ByteRate
A byte throughput: a producer quota, a replication rate, a measured send/receive rate.
ByteSize
A count of bytes: a message size, a segment size, a buffer capacity, a quota balance.
Frequency
An event rate: records per second, requests per second, polls per second.
Ratio
A dimensionless fraction: a fill factor, a sampling probability, a percentage.
Time
An extent of time: a timeout, a retention window, a backoff, a measured latency.