Bedrock.SystemKeys.Reader (bedrock v0.7.0)
View SourceThe shared readers for the durable \xFF/system mapping families:
paged range reads and the family decoders. Recovery's materializer
bootstrap and the Distributor both read the same families the same
way — one reader, so two consumers cannot disagree about what the
bytes mean.
Paging resumes each page immediately after the last returned key and drains the continuation to exhaustion: a truncated boundary map is not a degraded layout, it is a wrong one. Any failure mid-continuation fails the whole read — partial success would BE the silent truncation this exists to preclude — and an empty page claiming more is a broken read contract, surfaced rather than looped on.
Summary
Functions
Decodes materializers/<tag>/<worker_id> entries into the membership
map %{tag => %{worker_id => node}} - a shard's members are a set, and
absence of a key is absence of a member.
Reads a system family's entries to exhaustion, starting at prefix.
Decodes shard_keys/<end_key> entries into the boundary map
%{end_key => {tag, start_key}}, consuming the carried start key
verbatim — the same meaning RoutingData.apply_mutation gives the
value; two readers of one family must not disagree. Adjacency
reconstruction (each shard starts where the previous ends) survives
only for legacy term_to_binary snapshots that predate carried start
keys; recovery no longer rewrites the family (read-and-heal,
bedrock-q67.21.2), so a legacy family stays legacy — encoding-uniform,
covered by the any-legacy-falls-back-whole rule — until
bedrock-q67.20.7 retires the fallback with an explicit migration.
Types
@type range_read_fn() :: (Bedrock.key() -> {:ok, {[{Bedrock.key(), binary()}], more :: boolean()}} | {:error, term()} | {:failure, term(), term()})
Functions
@spec decode_materializer_members([{Bedrock.key(), binary()}]) :: {:ok, %{ required(Bedrock.range_tag()) => %{ required(Bedrock.Service.Worker.id()) => String.t() } }} | {:error, {:invalid_materializer_entry, Bedrock.key()}}
Decodes materializers/<tag>/<worker_id> entries into the membership
map %{tag => %{worker_id => node}} - a shard's members are a set, and
absence of a key is absence of a member.
A foreign key, or a member key with an undecodable value, fails the whole decode: reading a family we cannot account for as empty would re-recruit every shard and orphan the live ones.
@spec read_family(range_read_fn(), prefix :: Bedrock.key(), error_tag :: atom()) :: {:ok, [{Bedrock.key(), binary()}]} | {:error, {atom(), term()}}
Reads a system family's entries to exhaustion, starting at prefix.
@spec shard_layout_from_entries([{Bedrock.key(), binary()}]) :: {:ok, %{required(Bedrock.key()) => {Bedrock.range_tag(), Bedrock.key()}}} | {:error, {:invalid_shard_value, Bedrock.key()}}
Decodes shard_keys/<end_key> entries into the boundary map
%{end_key => {tag, start_key}}, consuming the carried start key
verbatim — the same meaning RoutingData.apply_mutation gives the
value; two readers of one family must not disagree. Adjacency
reconstruction (each shard starts where the previous ends) survives
only for legacy term_to_binary snapshots that predate carried start
keys; recovery no longer rewrites the family (read-and-heal,
bedrock-q67.21.2), so a legacy family stays legacy — encoding-uniform,
covered by the any-legacy-falls-back-whole rule — until
bedrock-q67.20.7 retires the fallback with an explicit migration.