pub struct TargetCost { /* private fields */ }Expand description
What one target costs, per refresh, in requests against the shared ceiling.
§Why an organization is not a constant
04-subsystem-contracts.md tabulates a flat “per target, per hour” cost —
~240 at the 60-second default, ~480 at the 30-second floor — and that table
is right for a repository target and wrong for an organization one. Two
of the three request classes are per-repository resources:
| Class | Repository target | Organization target with n installed repositories |
|---|---|---|
| runner inventory | 1 | 1 (there is an org runners endpoint) |
| in-progress workflow count | 1 | n |
| demand: queued runs plus jobs | 2 | 2n |
| per refresh | 4 | 1 + 3n |
At n = 1 the two agree exactly, at 4 requests per refresh and 240 per hour
at the default interval, which is what makes this a refinement of the
documented table rather than a contradiction of it. At n = 10 an
organization costs 31 requests per refresh — nearly eight times a repository
— and projecting it as one flat target understates the real spend by exactly
that factor. f2’s org add refusal therefore arrives much earlier than a
repository’s would, which is a thing it has to be able to explain.
§What this model does not claim
It is a projection of steady-state polling, in whole requests per refresh.
It does not model a target whose runner inventory spans pages (a second page
is a second request), an interactive auth status, a JIT registration, or a
runner deletion. That is what BUDGET_SHARE_DIVISOR is for: the
projection is compared against half the ceiling, and the other half absorbs
everything this model deliberately does not attempt to count.
It also prices each repository’s activity count at its best case of one
request. A count that has to take the no-total_count fallback costs up to
MAX_ACTIVITY_FALLBACK_PAGES — see
ACTIVITY_REQUESTS_PER_REPOSITORY_PER_REFRESH, which f1 and f2 read
directly.
Implementations§
Source§impl TargetCost
impl TargetCost
Sourcepub const fn repository() -> Self
pub const fn repository() -> Self
A repository target: one repository, by construction.
Sourcepub const fn organization(installed_repositories: u32) -> Self
pub const fn organization(installed_repositories: u32) -> Self
An organization target reaching installed_repositories repositories.
Sourcepub fn with_demand_requests_per_repository(self, requests: u32) -> Self
pub fn with_demand_requests_per_repository(self, requests: u32) -> Self
Replace the demand cost with the one c4 measured.
c4’s specification says to “report the per-poll request count to c3’s
budget model rather than estimating it there”, and this is where it
reports it. Without a seam, honouring that sentence would mean editing
DEMAND_REQUESTS_PER_REPOSITORY_PER_REFRESH — in this file, which c4
does not own — so the sentence would have been unfollowable and the
estimate would have quietly stayed the truth.
The default is DEMAND_REQUESTS_PER_REPOSITORY_PER_REFRESH, which is
what 04-subsystem-contracts.md tabulates. This overrides that number
and nothing else: the inventory and activity costs are this task’s own
and are measured against the requests it really issues.
Sourcepub fn from_activity_scope(scope: &ActivityScope) -> Self
pub fn from_activity_scope(scope: &ActivityScope) -> Self
The cost of the scope an activity refresh will actually walk.
Preferred over TargetCost::organization wherever the repository set
is already in hand, because it takes the count from the same list the
requests will be issued against rather than from a number somebody
passed in.
pub const fn scope(&self) -> TargetScope
pub const fn installed_repositories(&self) -> u32
Sourcepub const fn requests_per_refresh(&self) -> u32
pub const fn requests_per_refresh(&self) -> u32
Requests one refresh of this target costs.
Sourcepub fn requests_per_hour(&self, interval: RefreshInterval) -> u32
pub fn requests_per_hour(&self, interval: RefreshInterval) -> u32
Requests one hour of refreshing this target at interval costs.
Trait Implementations§
Source§impl Clone for TargetCost
impl Clone for TargetCost
Source§fn clone(&self) -> TargetCost
fn clone(&self) -> TargetCost
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for TargetCost
Source§impl Debug for TargetCost
impl Debug for TargetCost
impl Eq for TargetCost
Source§impl PartialEq for TargetCost
impl PartialEq for TargetCost
impl StructuralPartialEq for TargetCost
Auto Trait Implementations§
impl Freeze for TargetCost
impl RefUnwindSafe for TargetCost
impl Send for TargetCost
impl Sync for TargetCost
impl Unpin for TargetCost
impl UnsafeUnpin for TargetCost
impl UnwindSafe for TargetCost
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.