Skip to main content

Module provider

Module provider 

Source
Expand description

“Which backends can give me all of this?” The consumer lists the capabilities it needs (ProviderNeeds); providers returns every Provider in a table whose recorded matrix rows say yes to every one, and whose declared durability reaches the minimum. rank orders those with choose. Nothing here opens a backend: opening is the facade’s registry (a provider says what endpoint it needs, EndpointSpec, and nothing more).

The rules are docs/DESIGN-KINDS.md section 2.1’s, applied to a field of providers instead of one named backend:

  • A capability is a boolean. A provider has it only if the Matrix says Lookup::On on one of its Surfaces and Lookup::Off on none. No row is off.
  • No closest match. If no provider satisfies every need, the answer is Unmet: for each provider, each needed id it lacks (with the matrix’s own word, Lookup) and any durability shortfall. A partial list is never returned.
  • The table is data the caller passes in; this module holds no registry and does no I/O.
use persistant_core::{CapabilityId, Config, Matrix};
use persistant_core::choose::Durability;
use persistant_core::provider::{providers, EndpointSpec, Provider, ProviderNeeds, Surface};

let matrix = Matrix::parse("subject_kind\tsubject\tbackend\tversion\tconfig\tenabled\treason\tmetadata\tnote\n\
    capability\tkv.get\tmem\t1\t\tyes\t\t\t\n").unwrap();
let table = [Provider::new("mem", vec![Surface::new("mem", "1", Config::new())], None, EndpointSpec::None)];
let needs = ProviderNeeds::new(vec![CapabilityId::new("kv.get").unwrap()], Durability::Volatile);
assert_eq!(providers(&table, &needs, &matrix).unwrap().len(), 1);
let needs = ProviderNeeds::new(vec![CapabilityId::new("kv.ttl").unwrap()], Durability::Volatile);
assert!(providers(&table, &needs, &matrix).is_err()); // names `kv.ttl` as unmet on `mem`

From providers() to a working handle (the open half lands with the facade’s registry):

  1. build a ProviderNeeds from the capability ids and the lowest durability you accept;
  2. call providers with the table and the matrix; Err(Unmet) names what each backend lacks;
  3. optionally rank the result by a measured workload;
  4. take the first Provider; its EndpointSpec says whether it needs a path, a URL or nothing;
  5. pass it and your endpoint to the registry’s open for a handle.

Structs§

Provider
A backend a program could be given: what the matrix is asked about, what it declares about durability, and what endpoint it needs to be opened.
ProviderNeeds
What the program needs: capability ids that must all be on, and the lowest durability class.
ProviderUnmet
What one provider lacks.
Sorted
One provider in a sorted answer, with what it was sorted on.
Surface
One place the matrix records facts about a provider: a (backend, version, config) triple. A provider that is a kind built on another (key-value on PostgreSQL) has one surface per layer, because the matrix files name them separately (kv-on-relational:postgres and postgres).
Unmet
No provider satisfies the whole need. Lists every provider considered with what it lacks.

Enums§

DurabilityShortfall
Why a provider’s durability fell short.
EndpointSpec
What a provider needs to be told to open: the endpoint information a configuration cannot guess.

Functions§

providers
Every provider in table that has all of needs, in table order.
rank
Order qualified (the result of providers) with choose: fastest median first for need.rank_by in need.environment, matched on each provider’s primary surface. Eligibility comes from the recorded rows already checked, so need.leaves is not consulted. A provider with no measurement is listed as unmeasured, not hidden; if none is measured the result is the error that carries them.
select
providers then sorted: the one call a setup UI makes.
sorted
Order qualified (the result of providers) for a setup UI: by the preferred ids in order of importance (a provider having the first preferred id outranks any that lacks it, whatever the rest), then by measured median time, smaller first, with unmeasured last, then by name. Nothing is dropped: every provider passed in is in the result, with the evidence it was sorted on. speed is the Need naming the workload and environment, and the table; without it nothing is measured.