-module(lightspeed@cluster@durable_backend).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/cluster/durable_backend.gleam").
-export([expanded_backends/0, default_slo_budgets/0, valid/1, backend_matrix_certified/0, run_pressure_matrix/0, takeover_fencing_recovery_certified/0, evaluate_slo_budget/2, budget_failures/1, backend_class_label/1, pressure_label/1, artifact_signature/1, backend_signature/1, observation_signature/1, budget_result_signature/1, matrix_signature/0, name/1, artifact/1]).
-export_type([backend_class/0, pressure_profile/0, certification_artifact/0, backend_contract/0, observation/0, slo_budget/0, budget_result/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(" Durable backend conformance contracts for M49.\n").
-type backend_class() :: sql_quorum |
kv_consensus |
log_replicated |
object_manifest.
-type pressure_profile() :: nominal |
dependency_degraded |
dependency_partitioned.
-type certification_artifact() :: {certification_artifact,
binary(),
binary(),
binary()}.
-type backend_contract() :: {backend_contract,
binary(),
backend_class(),
binary(),
boolean(),
boolean(),
integer(),
integer(),
list(pressure_profile()),
certification_artifact()}.
-type observation() :: {observation,
binary(),
pressure_profile(),
integer(),
integer(),
integer(),
integer(),
boolean()}.
-type slo_budget() :: {slo_budget,
pressure_profile(),
integer(),
integer(),
integer()}.
-type budget_result() :: {budget_result,
binary(),
pressure_profile(),
boolean(),
binary()}.
-file("src/lightspeed/cluster/durable_backend.gleam", 80).
?DOC(" Expanded M49 backend matrix.\n").
-spec expanded_backends() -> list(backend_contract()).
expanded_backends() ->
[{backend_contract,
<<"postgres_wal_quorum"/utf8>>,
sql_quorum,
<<"postgres://cluster/wal"/utf8>>,
true,
true,
70,
1,
[nominal, dependency_degraded, dependency_partitioned],
{certification_artifact,
<<"docs/backend_failover_tuning_and_certification.md#postgres-wal-quorum"/utf8>>,
<<"docs/reports/durable_backend_fixture_latest.md#postgres_wal_quorum"/utf8>>,
<<"ops/certification/postgres_wal_quorum.md"/utf8>>}},
{backend_contract,
<<"foundationdb_consensus"/utf8>>,
kv_consensus,
<<"foundationdb://cluster/default"/utf8>>,
true,
true,
68,
1,
[nominal, dependency_degraded, dependency_partitioned],
{certification_artifact,
<<"docs/backend_failover_tuning_and_certification.md#foundationdb-consensus"/utf8>>,
<<"docs/reports/durable_backend_fixture_latest.md#foundationdb_consensus"/utf8>>,
<<"ops/certification/foundationdb_consensus.md"/utf8>>}},
{backend_contract,
<<"etcd_lease_journal"/utf8>>,
log_replicated,
<<"etcd://cluster/leases"/utf8>>,
true,
true,
72,
2,
[nominal, dependency_degraded, dependency_partitioned],
{certification_artifact,
<<"docs/backend_failover_tuning_and_certification.md#etcd-lease-journal"/utf8>>,
<<"docs/reports/durable_backend_fixture_latest.md#etcd_lease_journal"/utf8>>,
<<"ops/certification/etcd_lease_journal.md"/utf8>>}},
{backend_contract,
<<"object_manifest_journal"/utf8>>,
object_manifest,
<<"s3://durable/manifests"/utf8>>,
true,
true,
82,
2,
[nominal, dependency_degraded, dependency_partitioned],
{certification_artifact,
<<"docs/backend_failover_tuning_and_certification.md#object-manifest-journal"/utf8>>,
<<"docs/reports/durable_backend_fixture_latest.md#object_manifest_journal"/utf8>>,
<<"ops/certification/object_manifest_journal.md"/utf8>>}}].
-file("src/lightspeed/cluster/durable_backend.gleam", 162).
?DOC(" Deterministic M49 pressure budgets.\n").
-spec default_slo_budgets() -> list(slo_budget()).
default_slo_budgets() ->
[{slo_budget, nominal, 55, 95, 1},
{slo_budget, dependency_degraded, 70, 112, 2},
{slo_budget, dependency_partitioned, 88, 130, 2}].
-file("src/lightspeed/cluster/durable_backend.gleam", 333).
-spec artifact_valid(certification_artifact()) -> boolean().
artifact_valid(Artifact) ->
(gleam_stdlib:string_starts_with(
erlang:element(2, Artifact),
<<"docs/"/utf8>>
)
andalso gleam_stdlib:string_starts_with(
erlang:element(3, Artifact),
<<"docs/reports/"/utf8>>
))
andalso gleam_stdlib:string_starts_with(
erlang:element(4, Artifact),
<<"ops/"/utf8>>
).
-file("src/lightspeed/cluster/durable_backend.gleam", 186).
?DOC(" Validate one backend contract.\n").
-spec valid(backend_contract()) -> boolean().
valid(Backend) ->
(((((((erlang:element(2, Backend) /= <<""/utf8>>) andalso (erlang:element(
4,
Backend
)
/= <<""/utf8>>))
andalso erlang:element(5, Backend))
andalso erlang:element(6, Backend))
andalso (erlang:element(7, Backend) > 0))
andalso (erlang:element(8, Backend) >= 0))
andalso (erlang:element(9, Backend) /= []))
andalso artifact_valid(erlang:element(10, Backend)).
-file("src/lightspeed/cluster/durable_backend.gleam", 360).
-spec contains_string(list(binary()), binary()) -> boolean().
contains_string(Values, Expected) ->
case Values of
[] ->
false;
[Value | Rest] ->
(Value =:= Expected) orelse contains_string(Rest, Expected)
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 346).
-spec unique_backend_names(list(backend_contract()), list(binary())) -> boolean().
unique_backend_names(Backends, Seen) ->
case Backends of
[] ->
true;
[Backend | Rest] ->
case contains_string(Seen, erlang:element(2, Backend)) of
true ->
false;
false ->
unique_backend_names(
Rest,
[erlang:element(2, Backend) | Seen]
)
end
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 339).
-spec all_backends_valid(list(backend_contract())) -> boolean().
all_backends_valid(Backends) ->
case Backends of
[] ->
true;
[Backend | Rest] ->
valid(Backend) andalso all_backends_valid(Rest)
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 198).
?DOC(" Deterministic M49 backend-matrix certification invariant.\n").
-spec backend_matrix_certified() -> boolean().
backend_matrix_certified() ->
Backends = expanded_backends(),
((erlang:length(Backends) =:= 4) andalso all_backends_valid(Backends))
andalso unique_backend_names(Backends, []).
-file("src/lightspeed/cluster/durable_backend.gleam", 454).
-spec all_observations_fencing(list(observation())) -> boolean().
all_observations_fencing(Observations) ->
case Observations of
[] ->
true;
[Observation | Rest] ->
(erlang:element(6, Observation) >= 1) andalso all_observations_fencing(
Rest
)
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 446).
-spec all_observations_continuity(list(observation())) -> boolean().
all_observations_continuity(Observations) ->
case Observations of
[] ->
true;
[Observation | Rest] ->
erlang:element(8, Observation) andalso all_observations_continuity(
Rest
)
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 383).
-spec prepend_reversed(list(observation()), list(observation())) -> list(observation()).
prepend_reversed(Values, Target) ->
case Values of
[] ->
Target;
[Value | Rest] ->
prepend_reversed(Rest, [Value | Target])
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 438).
-spec pressure_adjustment(pressure_profile()) -> {integer(),
integer(),
integer(),
integer()}.
pressure_adjustment(Pressure) ->
case Pressure of
nominal ->
{0, 0, 0, 0};
dependency_degraded ->
{10, 16, 1, 0};
dependency_partitioned ->
{22, 28, 2, 1}
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 429).
-spec class_baseline(backend_class()) -> {integer(),
integer(),
integer(),
integer()}.
class_baseline(Class) ->
case Class of
sql_quorum ->
{24, 58, 2, 0};
kv_consensus ->
{20, 52, 2, 0};
log_replicated ->
{23, 56, 2, 1};
object_manifest ->
{28, 64, 1, 1}
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 401).
-spec simulate_failover(backend_contract(), pressure_profile()) -> observation().
simulate_failover(Backend, Pressure) ->
{Base_takeover, Base_recovery, Base_fence_rejections, Base_data_loss} = class_baseline(
erlang:element(3, Backend)
),
{Takeover_delta, Recovery_delta, Fence_delta, Data_loss_delta} = pressure_adjustment(
Pressure
),
Takeover_ms = Base_takeover + Takeover_delta,
Recovery_ms = Base_recovery + Recovery_delta,
Fence_rejections = Base_fence_rejections + Fence_delta,
Data_loss_events = Base_data_loss + Data_loss_delta,
Continuity_met = ((Takeover_ms =< erlang:element(7, Backend)) andalso (Recovery_ms
=< (erlang:element(7, Backend) + 48)))
andalso (Data_loss_events =< erlang:element(8, Backend)),
{observation,
erlang:element(2, Backend),
Pressure,
Takeover_ms,
Recovery_ms,
Fence_rejections,
Data_loss_events,
Continuity_met}.
-file("src/lightspeed/cluster/durable_backend.gleam", 393).
-spec run_pressure_matrix_one_backend(backend_contract()) -> list(observation()).
run_pressure_matrix_one_backend(Backend) ->
gleam@list:map(
erlang:element(9, Backend),
fun(Pressure) -> simulate_failover(Backend, Pressure) end
).
-file("src/lightspeed/cluster/durable_backend.gleam", 367).
-spec run_pressure_matrix_backends(
list(backend_contract()),
list(observation())
) -> list(observation()).
run_pressure_matrix_backends(Backends, Observations_rev) ->
case Backends of
[] ->
lists:reverse(Observations_rev);
[Backend | Rest] ->
Backend_observations = run_pressure_matrix_one_backend(Backend),
run_pressure_matrix_backends(
Rest,
prepend_reversed(Backend_observations, Observations_rev)
)
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 215).
?DOC(" Run deterministic pressure matrix across all expanded backends.\n").
-spec run_pressure_matrix() -> list(observation()).
run_pressure_matrix() ->
run_pressure_matrix_backends(expanded_backends(), []).
-file("src/lightspeed/cluster/durable_backend.gleam", 207).
?DOC(" Deterministic takeover/fencing/recovery semantics certification.\n").
-spec takeover_fencing_recovery_certified() -> boolean().
takeover_fencing_recovery_certified() ->
Observations = run_pressure_matrix(),
all_observations_continuity(Observations) andalso all_observations_fencing(
Observations
).
-file("src/lightspeed/cluster/durable_backend.gleam", 532).
-spec bool_label(boolean()) -> binary().
bool_label(Value) ->
case Value of
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 518).
-spec budget_for_pressure(pressure_profile(), list(slo_budget())) -> {ok,
slo_budget()} |
{error, binary()}.
budget_for_pressure(Pressure, Budgets) ->
case Budgets of
[] ->
{error, <<"missing_pressure_budget"/utf8>>};
[Budget | Rest] ->
case erlang:element(2, Budget) =:= Pressure of
true ->
{ok, Budget};
false ->
budget_for_pressure(Pressure, Rest)
end
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 476).
-spec evaluate_one_budget(observation(), list(slo_budget())) -> budget_result().
evaluate_one_budget(Observation, Budgets) ->
case budget_for_pressure(erlang:element(3, Observation), Budgets) of
{error, Reason} ->
{budget_result,
erlang:element(2, Observation),
erlang:element(3, Observation),
false,
Reason};
{ok, Budget} ->
Takeover_ok = erlang:element(4, Observation) =< erlang:element(
3,
Budget
),
Recovery_ok = erlang:element(5, Observation) =< erlang:element(
4,
Budget
),
Loss_ok = erlang:element(7, Observation) =< erlang:element(
5,
Budget
),
Continuity_ok = erlang:element(8, Observation),
Passed = ((Takeover_ok andalso Recovery_ok) andalso Loss_ok) andalso Continuity_ok,
Reason@1 = case Passed of
true ->
<<"within_budget"/utf8>>;
false ->
<<<<<<<<<<<<<<<<"budget_exceeded:"/utf8, "takeover="/utf8>>/binary,
(bool_label(Takeover_ok))/binary>>/binary,
":recovery="/utf8>>/binary,
(bool_label(Recovery_ok))/binary>>/binary,
":data_loss="/utf8>>/binary,
(bool_label(Loss_ok))/binary>>/binary,
":continuity="/utf8>>/binary,
(bool_label(Continuity_ok))/binary>>
end,
{budget_result,
erlang:element(2, Observation),
erlang:element(3, Observation),
Passed,
Reason@1}
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 462).
-spec evaluate_budget_loop(
list(observation()),
list(slo_budget()),
list(budget_result())
) -> list(budget_result()).
evaluate_budget_loop(Observations, Budgets, Results_rev) ->
case Observations of
[] ->
lists:reverse(Results_rev);
[Observation | Rest] ->
Result = evaluate_one_budget(Observation, Budgets),
evaluate_budget_loop(Rest, Budgets, [Result | Results_rev])
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 220).
?DOC(" Evaluate one pressure-matrix run against one SLO budget profile.\n").
-spec evaluate_slo_budget(list(observation()), list(slo_budget())) -> list(budget_result()).
evaluate_slo_budget(Observations, Budgets) ->
evaluate_budget_loop(Observations, Budgets, []).
-file("src/lightspeed/cluster/durable_backend.gleam", 228).
?DOC(" Count failing budget checks.\n").
-spec budget_failures(list(budget_result())) -> integer().
budget_failures(Results) ->
case Results of
[] ->
0;
[Result | Rest] ->
case erlang:element(4, Result) of
true ->
budget_failures(Rest);
false ->
1 + budget_failures(Rest)
end
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 240).
?DOC(" Stable backend-class label.\n").
-spec backend_class_label(backend_class()) -> binary().
backend_class_label(Class) ->
case Class of
sql_quorum ->
<<"sql_quorum"/utf8>>;
kv_consensus ->
<<"kv_consensus"/utf8>>;
log_replicated ->
<<"log_replicated"/utf8>>;
object_manifest ->
<<"object_manifest"/utf8>>
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 250).
?DOC(" Stable pressure label.\n").
-spec pressure_label(pressure_profile()) -> binary().
pressure_label(Pressure) ->
case Pressure of
nominal ->
<<"nominal"/utf8>>;
dependency_degraded ->
<<"dependency_degraded"/utf8>>;
dependency_partitioned ->
<<"dependency_partitioned"/utf8>>
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 259).
?DOC(" Stable artifact signature.\n").
-spec artifact_signature(certification_artifact()) -> binary().
artifact_signature(Artifact) ->
<<<<<<<<<<"tuning="/utf8, (erlang:element(2, Artifact))/binary>>/binary,
"|certification="/utf8>>/binary,
(erlang:element(3, Artifact))/binary>>/binary,
"|evidence="/utf8>>/binary,
(erlang:element(4, Artifact))/binary>>.
-file("src/lightspeed/cluster/durable_backend.gleam", 539).
-spec join_with(binary(), list(binary())) -> binary().
join_with(Separator, Values) ->
case Values of
[] ->
<<""/utf8>>;
[Value] ->
Value;
[Value@1 | Rest] ->
<<<<Value@1/binary, Separator/binary>>/binary,
(join_with(Separator, Rest))/binary>>
end.
-file("src/lightspeed/cluster/durable_backend.gleam", 269).
?DOC(" Stable backend signature.\n").
-spec backend_signature(backend_contract()) -> binary().
backend_signature(Backend) ->
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"backend="/utf8,
(erlang:element(
2,
Backend
))/binary>>/binary,
"|class="/utf8>>/binary,
(backend_class_label(
erlang:element(
3,
Backend
)
))/binary>>/binary,
"|store="/utf8>>/binary,
(erlang:element(
4,
Backend
))/binary>>/binary,
"|fencing="/utf8>>/binary,
(bool_label(
erlang:element(5, Backend)
))/binary>>/binary,
"|replay="/utf8>>/binary,
(bool_label(erlang:element(6, Backend)))/binary>>/binary,
"|slo_ms="/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(7, Backend)
))/binary>>/binary,
"|max_data_loss="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(8, Backend)))/binary>>/binary,
"|pressures="/utf8>>/binary,
(join_with(
<<","/utf8>>,
gleam@list:map(
erlang:element(9, Backend),
fun pressure_label/1
)
))/binary>>/binary,
"|artifact="/utf8>>/binary,
(artifact_signature(erlang:element(10, Backend)))/binary>>.
-file("src/lightspeed/cluster/durable_backend.gleam", 291).
?DOC(" Stable pressure observation signature.\n").
-spec observation_signature(observation()) -> binary().
observation_signature(Observation) ->
<<<<<<<<<<<<<<<<<<<<<<<<(erlang:element(2, Observation))/binary,
":pressure="/utf8>>/binary,
(pressure_label(
erlang:element(
3,
Observation
)
))/binary>>/binary,
":takeover_ms="/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(4, Observation)
))/binary>>/binary,
":recovery_ms="/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(5, Observation)
))/binary>>/binary,
":fence_rejections="/utf8>>/binary,
(erlang:integer_to_binary(
erlang:element(6, Observation)
))/binary>>/binary,
":data_loss_events="/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(7, Observation)))/binary>>/binary,
":continuity_met="/utf8>>/binary,
(bool_label(erlang:element(8, Observation)))/binary>>.
-file("src/lightspeed/cluster/durable_backend.gleam", 308).
?DOC(" Stable budget-result signature.\n").
-spec budget_result_signature(budget_result()) -> binary().
budget_result_signature(Result) ->
<<<<<<<<<<<<(erlang:element(2, Result))/binary, ":pressure="/utf8>>/binary,
(pressure_label(erlang:element(3, Result)))/binary>>/binary,
":passed="/utf8>>/binary,
(bool_label(erlang:element(4, Result)))/binary>>/binary,
":reason="/utf8>>/binary,
(erlang:element(5, Result))/binary>>.
-file("src/lightspeed/cluster/durable_backend.gleam", 319).
?DOC(" Stable matrix signature across expanded backends.\n").
-spec matrix_signature() -> binary().
matrix_signature() ->
join_with(
<<";"/utf8>>,
gleam@list:map(expanded_backends(), fun backend_signature/1)
).
-file("src/lightspeed/cluster/durable_backend.gleam", 324).
?DOC(" Backend name accessor.\n").
-spec name(backend_contract()) -> binary().
name(Backend) ->
erlang:element(2, Backend).
-file("src/lightspeed/cluster/durable_backend.gleam", 329).
?DOC(" Backend artifact accessor.\n").
-spec artifact(backend_contract()) -> certification_artifact().
artifact(Backend) ->
erlang:element(10, Backend).