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 serdeadapters, 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
nbytes.- bytes_
per_ sec nbytes per second.- days
ndays.- fraction
- A dimensionless fraction, where
1.0is the whole. - gibibytes
ngibibytes (1 GiB = 1024 MiB).- gibibytes_
per_ sec ngibibytes per second.- hours
nhours.- kibibytes
nkibibytes (1 KiB = 1024 B).- kibibytes_
per_ sec nkibibytes per second.- mebibytes
nmebibytes (1 MiB = 1024 KiB).- mebibytes_
per_ sec nmebibytes per second.- micros
nmicroseconds.- millis
nmilliseconds.- minutes
nminutes.- nanos
nnanoseconds.- per_sec
nevents per second.- percent
npercent, as a dimensionlessRatio(percent(25) == fraction(0.25)).- secs
nseconds.
Type Aliases§
- Byte
Rate - A byte throughput: a producer quota, a replication rate, a measured send/receive rate.
- Byte
Size - 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.