pub struct ActivityCount { /* private fields */ }Expand description
In-progress workflow runs, per repository and in total.
Not the busy-runner count. A workflow run is work GitHub has accepted and
started; a busy runner is a machine executing a job. One run can occupy
several runners, a run can be in progress with none of its jobs assigned yet,
and a busy runner may be executing a job for a workflow this product does not
poll at all. 04-subsystem-contracts.md and g2 both require them rendered
as distinct aggregates, and they are distinct types here so that they cannot
be added together by accident.
§A count can be short in two different ways, and both have to say so
A repository can fail to answer at all (ActivityCount::unavailable), and
a repository can answer with a number that is only a floor
(ActivityCount::truncated) — the fallback walk stopped at
MAX_ACTIVITY_FALLBACK_PAGES, or GitHub’s own total was wider than the
u32 this product renders. ActivityCount::is_complete is false for
either, because 04-subsystem-contracts.md forbids exactly this shape of
mistake on the other read model — “must never treat a first page as a
complete inventory” — and a count truncated at page four is the same defect
wearing a different endpoint.
Implementations§
Source§impl ActivityCount
impl ActivityCount
pub fn new(per_repository: BTreeMap<OwnerRepo, u32>) -> Self
Sourcepub fn of(repository: OwnerRepo, count: u32) -> Self
pub fn of(repository: OwnerRepo, count: u32) -> Self
One repository’s count, for the common single-repository case.
Sourcepub fn with_truncated(self, repository: OwnerRepo) -> Self
pub fn with_truncated(self, repository: OwnerRepo) -> Self
Mark repository’s count a floor rather than a total.
The programmable counterpart to what the fallback walk does when it stops
at MAX_ACTIVITY_FALLBACK_PAGES, and it exists so that the incomplete
case is reachable from outside this module at all. Self::new and
Self::of were the only public constructors; both yield an empty
truncated and an empty unavailable, and the fields are private —
so Self::is_complete could only ever be true for a caller holding a
hand-built count, and every downstream consumer that renders the false
path had no way to write a test for it.
Record a repository the count could not read, and why.
The counterpart to Self::with_truncated for the other cause of an
incomplete count — see Self::is_complete for why the two are not
interchangeable. Deliberately does not insert a zero into
Self::per_repository: a repository that could not be counted is
unknown, not idle, and flattening it to zero is the exact defect
UnavailableRepository exists to prevent.
Sourcepub fn total(&self) -> u32
pub fn total(&self) -> u32
In-progress workflow runs across every repository in scope.
A floor rather than a total when Self::truncated is non-empty,
and short by an unknown amount when Self::unavailable is. Both make
Self::is_complete false, which is the one question a caller
rendering this number has to ask.
pub fn per_repository(&self) -> &BTreeMap<OwnerRepo, u32>
Sourcepub fn for_repository(&self, repository: &OwnerRepo) -> Option<u32>
pub fn for_repository(&self, repository: &OwnerRepo) -> Option<u32>
This repository’s count, or None when it was not in scope.
Sourcepub fn truncated(&self) -> &BTreeSet<OwnerRepo>
pub fn truncated(&self) -> &BTreeSet<OwnerRepo>
Repositories whose count is a floor, not a total.
The counterpart to RunnerInventory::truncated, and here for the same
reason: a number clipped by a page ceiling that does not say it was
clipped is indistinguishable from a real one, and g2 renders this
number with no other way to find out.
Sourcepub fn is_truncated(&self, repository: &OwnerRepo) -> bool
pub fn is_truncated(&self, repository: &OwnerRepo) -> bool
Whether this repository’s count is a floor rather than a total.
Sourcepub fn is_complete(&self) -> bool
pub fn is_complete(&self) -> bool
true when every repository in scope answered and every answer was
exact.
Deliberately one question rather than two. A caller that has to remember
to ask about truncation separately is a caller that will forget, which is
the same argument is_repository_local_failure makes about stepping over
the only repository in scope.
§false has two causes, and they have opposite remedies
One question is right for rendering the number. It is not enough for acting on it, because the two ways a count can be incomplete point in opposite directions:
Self::truncated— the count is a lower bound. The repository answered and there is at least this much work in progress, so scaling up from it is sound; the real figure is only ever larger.Self::unavailable— the count is unknown. Nothing was learned about that repository, and a missing count is not a zero. Scaling on it is guessing.
So a caller that reads false as a uniform “do nothing” stalls scale-up
on a repository that is demonstrably busy — the truncated case is
evidence of load, not absence of it. Ask this question to decide
whether to caveat the number; ask Self::truncated versus
Self::unavailable to decide what to do about it.
Trait Implementations§
Source§impl Clone for ActivityCount
impl Clone for ActivityCount
Source§fn clone(&self) -> ActivityCount
fn clone(&self) -> ActivityCount
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ActivityCount
impl Debug for ActivityCount
Source§impl Default for ActivityCount
impl Default for ActivityCount
Source§fn default() -> ActivityCount
fn default() -> ActivityCount
impl Eq for ActivityCount
Source§impl PartialEq for ActivityCount
impl PartialEq for ActivityCount
impl StructuralPartialEq for ActivityCount
Auto Trait Implementations§
impl Freeze for ActivityCount
impl RefUnwindSafe for ActivityCount
impl Send for ActivityCount
impl Sync for ActivityCount
impl Unpin for ActivityCount
impl UnsafeUnpin for ActivityCount
impl UnwindSafe for ActivityCount
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.