Skip to main content

AnalysisBudget

Struct AnalysisBudget 

Source
pub struct AnalysisBudget { /* private fields */ }
Expand description

The run’s budget for host-side type-provider work.

§Why this is a second clock rather than a share of RunClock

RunClock bounds guest execution and is polled from inside a handler by both engines. A tsc provider’s cost is neither: it is the user’s own TypeScript program being built, in a process lanekeep spawned, while no rule is running. Charging it to the run budget would make a cold provider run and a warm one take different exits over identical input, which is the determinism argument architecture §6.8 already makes for taking component compilation off the run clock.

§Why an accumulator rather than a wall clock

This budget is analysis time, not elapsed time. An Instant taken at prepare charges discovery, hashing, parsing, matching and every rule that ran to a budget whose own breach message says it is “the cost of building the project’s own TypeScript program and not of running any rule” — so the message would be a lie, and a large corpus whose program build takes half a minute would be cancelled for spending the rest of the minute doing the work the run exists to do. Only what AnalysisBudget::charge brackets is charged.

It is the mirror image of Budget::pause in intent: the rule clock stops where the analysis clock runs, so no instant is charged to both.

The converse does not hold, and that is deliberate. What a provider charges is service time — the window in which its sidecar is working on one request — so an instant a worker spends queued behind another worker’s request is charged to neither clock. Charging the queue wait instead would make the accumulator grow with the number of rayon workers rather than with the work: measured through the tsc provider, fourteen workers each waiting about 200 ms charged 2.866 s against 205 ms of wall clock, so a 60 s budget bounded roughly 60/P seconds of real analysis and the breach message quoted a duration nobody could observe. One sidecar serves the run, so the sum of its service times is the wall time it was busy — which is exactly what “type analysis took …” claims to name.

Clone over a shared accumulator rather than Copy over an Instant: the engine holds one and the provider holds another, and a charge on either has to be visible to the check the other makes. Two clones are the same budget, not two budgets.

Implementations§

Source§

impl AnalysisBudget

Source

pub fn start(budget: Duration) -> Self

A budget with nothing spent yet.

Source

pub const fn budget(&self) -> Duration

The configured budget, for a diagnostic.

Source

pub fn spent(&self) -> Duration

How much analysis time has been charged.

Source

pub fn charge(&self) -> Charge<'_>

Charge everything until the returned guard drops to this budget.

A guard rather than a matched pair for Paused’s reason: the call it brackets can return early on ?, and a stop whose start sits after a ? charges nothing for the one request that actually ran long.

Nesting composes by over-charging rather than by being forbidden — an inner charge’s time lands in the accumulator twice — so the caller brackets the outermost call it owns and nothing inside it.

Bracket the service, never the wait for it. A provider whose sidecar serves one request at a time must take this guard after it holds whatever serializes access, or every worker queued behind the one being served charges the queue and the accumulator counts the same instants once per waiting thread. See the type’s own documentation.

Source

pub fn remaining(&self) -> Option<Duration>

How much of it is left, or None once it is breached.

Some(Duration::ZERO) is a real answer and is not the same as None: a request handed a zero I/O timeout fails immediately and reports as a timeout, where None means the run is already over and nothing further should be attempted. The boundary is the same one analysis_overrun uses, so the two can never disagree about a single instant.

Source

pub fn overrun(&self) -> Option<String>

The diagnostic, if the budget is spent.

Trait Implementations§

Source§

impl Clone for AnalysisBudget

Source§

fn clone(&self) -> AnalysisBudget

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AnalysisBudget

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.