Expand description
The latest reading of a source, handed over at once.
CapabilityExecutor::execute answers a
question: it runs the handler, or returns an answer byte-identical to what the handler
would return (project.cache-is-invisible). A page a person is looking at asks for
something else. It wants what is known now, at once, with how old that is, and it
wants the answer to catch up behind it. That is a read, and it never passes itself
off as an answer: a Latest always carries when it was read, whether the repository
has moved since, and whether a newer reading is on its way.
§What a read costs
One lookup in this process’s memory. The handler, git and the file system are touched only by a worker of this module, off the path of the request:
- The source was read in the repository as it is now. The reading is returned
immediately. When it is older than
REVALIDATE, a worker reads it again behind the caller, so a source the repository does not determine (health, the mesh, the forge) stays close to the present without any reader waiting for it. - The repository has moved since. A worker reads the source again and the caller
waits for it for at most
Patience::moved. A fast source is therefore current on the same request; a slow one is returned as it was, markedFreshness::Staleandrefreshing. Every other source this process has been asked for lately is read again at the same moment, so the next screen a reader opens is ready before it is asked for. - The source has never been read here. There is nothing to hand over, so the caller
waits for the first reading, for at most
Patience::cold, and is toldFreshness::Pendingpast that.
One worker reads a source at a time, however many callers ask. The readings to take wait
in one queue, drained by at most WORKERS threads, so a change of the repository that
sends every remembered source to be read again starts no more threads than that. A
reading a caller is waiting for goes to the front of the queue and the ones nobody is
waiting for go to the back, so a reader never waits behind the background. Under the
workers the executor’s own cache and single flight still apply: a worker whose source
did not change is answered from the cache and costs nearly nothing.
§Switching it off
MAJORDOMUS_CAPABILITY_CACHE=off makes every read run its handler and wait for it, as
it makes every execute do. PATIENCE_SWITCH set to wait keeps the store and makes
every read wait for a current reading, which is what a test that changes a repository
and then reads a page needs in order to be exact.
§A reading, from first to known
use majordomus_cli::capability::readings::{read, Freshness, Patience};
use majordomus_cli::synthetic::SyntheticRepository;
use serde_json::json;
let repo = SyntheticRepository::small().unwrap();
let ctx = repo.context().unwrap();
// never read here: the caller waits for the first reading, and it is current
let first = read(&ctx, "plan.status", json!({}), Patience::WAIT);
assert_eq!(first.freshness, Freshness::Current);
assert!(first.value.is_ok() && first.read_at.is_some());
// known now: handed over from memory, with the age it has, and no handler runs for it
let ran = ctx.executor.handler_invocations();
let again = read(&ctx, "plan.status", json!({}), Patience::PAGE);
assert_eq!(again.value, first.value);
assert!(again.age.is_some() && !again.catching_up());
assert_eq!(ctx.executor.handler_invocations(), ran);
// a source that cannot answer is a reading that says why, never a missing one
let unknown = read(&ctx, "no.such.capability", json!({}), Patience::WAIT);
assert!(unknown.value.is_err());
assert_eq!(unknown.freshness, Freshness::Current);Structs§
- Latest
- The latest reading of one source.
- Patience
- How long a read waits for a worker before it returns what it has.
Enums§
- Freshness
- How a reading stands against the repository as it is now.
Constants§
- MAX_
SOURCES - The most sources remembered at once; the one asked for longest ago is dropped first.
- PATIENCE_
SWITCH - The environment variable that sets how long a read waits: a number of milliseconds for
a source whose repository has moved, or
waitto wait for a current reading every time. - PENDING
- What the first reading of a source says while it has not arrived.
- REMEMBERED
- How long a source nobody asked for is remembered, and so read again when the repository moves. A page left open asks for its sources every minute, so its sources stay; a screen nobody has looked at for five minutes stops costing anything when the repository changes.
- REVALIDATE
- How old a reading of the repository as it is now may grow before a worker reads its source again behind the caller.
- WORKERS
- How many sources are read at once by this module’s workers, all sources together.
Functions§
- read
- The latest reading of
idasked withinput: what this process knows now, returned withinpatience, with a worker reading the source again behind the caller whenever what is known is not current. See the module for what each case costs.