Skip to main content

Timings

Struct Timings 

Source
pub struct Timings {
Show 33 fields pub server_create_lo_ms: u64, pub server_create_hi_ms: u64, pub server_delete_ms: u64, pub server_delete_per_volume_ms: u64, pub storage_create_ms: u64, pub storage_delete_ms: u64, pub stop_soft_ms: u64, pub stop_hard_ms: u64, pub start_ms: u64, pub resize_ms: u64, pub guest_install_ms: u64, pub guest_install_uart_lo_ms: u64, pub guest_install_uart_hi_ms: u64, pub provider_wall_lo_ms: u64, pub provider_wall_hi_ms: u64, pub template_first_boot_ms: u64, pub import_upload_ms_per_mib: u64, pub storage_sync_lo_ms: u64, pub storage_sync_hi_ms: u64, pub clone_online_ms: u64, pub clone_sync_lo_ms: u64, pub clone_sync_hi_ms: u64, pub clone_prepare_ms: u64, pub install_pass_lo_ms: u64, pub install_pass_hi_ms: u64, pub installer_started_ms: u64, pub installer_started_window_ms: u64, pub reboot_pass_lo_ms: u64, pub reboot_pass_hi_ms: u64, pub poweroff_notice_ms: u64, pub storage_grow_ms: u64, pub vnc_settle_ms: u64, pub sync_tail_maintenance_ms: u64,
}
Expand description

The measured durations. Milliseconds, because the guest install was measured at 10 011 ms and rounding it to 10 s throws away the only digit that says it was measured.

Fields§

§server_create_lo_ms: u64

98–105 s. MEASURED across the estate re-lays; the mock draws uniformly in the range from the run’s seed, because a client that happened to be tuned to 100 s exactly is a client that will break.

§server_create_hi_ms: u64§server_delete_ms: u64

≈60 s for a front or a twin: a server with its own boot disk and nothing else.

§server_delete_per_volume_ms: u64

The extra per attached member volume. MEASURED: an appliance carrying four member volumes stayed in maintenance for more than five minutes. 60 s + 4 × 65 s = 320 s, which is the >5 min that was seen.

§storage_create_ms: u64

A storage create: it is maintenance for this long before online.

§storage_delete_ms: u64

A storage delete.

§stop_soft_ms: u64

A soft stop that the guest answers.

§stop_hard_ms: u64

A hard stop: the plug, so it is quick.

§start_ms: u64

Start → started for a disk boot: ≈10 s. MEASURED 2026-09-19 (private-gunnar-ops RESUME-2026-09-19, “started in 10 s”). It was 20 000 here, unmeasured — behaviour 45.

§resize_ms: u64

A plan change (the resize proper), server already stopped.

§guest_install_ms: u64

10 011 ms, MEASURED under KVM on this estate’s own boxes: INSTALL-OK from the installer’s first instruction. Kept because it is a real measurement of a real thing — but it is NOT what the appliance does, see below.

§guest_install_uart_lo_ms: u64

2 001 / 2 751 / 4 752 ms, MEASURED on the appliance’s UART across three re-images. This is the guest’s own clock, observed from inside.

§guest_install_uart_hi_ms: u64§provider_wall_lo_ms: u64

110 000–253 000 ms, MEASURED by the ladder as install-time, wall, from outside, across the same three re-images.

Two observers, two orders of magnitude, one word. The installer is not slow — the PROVIDER is: create, media sync, firmware, boot order, DHCP. A bar set at 60 s against the ladder’s number reads RED forever and tempts somebody to move the bar, when the number to move is the provider’s and the thing to report is which observer said what. See Timings::reimage_observers.

§provider_wall_hi_ms: u64§template_first_boot_ms: u64

The Ubuntu template’s first boot, during which dpkg lock-frontend is held by unattended-upgrade-shutdown --wait-for-signal — for the LIFE of the boot, so apt-get update blocks rather than failing (behaviour 21). This is how long the mock’s guest stays in that state; the real one never leaves it.

§import_upload_ms_per_mib: u64

The upload itself. MEASURED: 43 485 184 bytes (41.47 MiB) created 09:36:16Z, completed 09:36:21Z — five seconds, so about 120 ms per MiB. read_bytes == written_bytes == 43485184, both checksums present, the sha256 matching the local file exactly.

§storage_sync_lo_ms: u64

The wait NOBODY is doing any work during. After every byte has arrived and been checksummed, the storage sits in syncing for this long. MEASURED 100–130 s: the poller read syncing at 65 s and at 97 s while the import object already said completed.

And it is paid TWICE per appliance re-image, by design: the ladder uploads the same 43 MB medium once as a CD-ROM and again as a virtio DISK, because korp-installer probes virtio and nothing else. Two POST /storage, two imports, two syncs — about four minutes of pure waiting per re-image.

§storage_sync_hi_ms: u64§clone_online_ms: u64

A clone, MEASURED 2026-09-20 (gunnar deploy/upcloud/tests/clone_probe.rs): the call 728 ms, then maintenanceonline in 47 s, with NO syncing at all. This crate said “NOT MEASURED” and made a clone sync like an import for years of storm; the measurement existed in the next repository over (ledger X3, behaviour 53).

§clone_sync_lo_ms: u64

The old pessimistic guess, kept by name only (crate::Fault::CloneSyncsLikeImport): the clone waits in syncing for this long, like an import. Contradicted by the measurement above.

§clone_sync_hi_ms: u64§clone_prepare_ms: u64

What a clone costs before the sync even starts (the volume is maintenance while the copy is set up). Used only under the guess.

§install_pass_lo_ms: u64

A start whose guest powers itself off inside the start operation. MEASURED 2026-09-19: POST /startmaintenance t+10…t+130 s → stopped at t+140 s, and 2026-09-15: stopped 146 s after. The API NEVER reads started (behaviour 46). Counted from the start call. This is the FLOOR the API reports even when a real guest behind the mock finished its install in 2 s: the API reports UpCloud time.

§install_pass_hi_ms: u64§installer_started_ms: u64

An installer start DOES read started — briefly. MEASURED 2026-09-21 08:42 (private-gunnar-ops .reimage/reinstall-receipt.json, the live re-image, done: true): step start at 377 421 ms, a read of started at 381 091 ms (“the hypervisor reports the installer running”), maintenance at 381 174 ms, stopped at 530 945 ms. The 2026-09-19 “never started” was polled every 10 s from t+10 s (RESUME-2026-09-19:17-23), which cannot see a window this short. So: started from installer_started_ms for installer_started_window_ms — the window is only BOUNDED by the reads (≤ 83 ms after one that saw it), not measured — then maintenance until the pass ends.

§installer_started_window_ms: u64§reboot_pass_lo_ms: u64

The REBOOTING medium’s pass (behaviour 69): 900–1100 s, read started throughout. gunnar deploy/upcloud plan.rs: every measured pass ≥ 900 s; 1000–1100 s live on 2026-09-08. At its end the guest reboots.

§reboot_pass_hi_ms: u64§poweroff_notice_ms: u64

The lag between the guest powering off and the API saying stopped, used only when a REAL guest outlives the floor above: the API may not say stopped while the machine still runs, and says it this long after the machine is gone. Bounded by the 10 s polls that measured it.

§storage_grow_ms: u64

A size grow: maintenance for 37 s, then online. MEASURED 2026-09-14 on a detached 1→2 GiB volume (DATA-SET-GROWTH-DESIGN §2). It was instant here (behaviour 55).

§vnc_settle_ms: u64

The VNC toggle’s settle. The PUT returns before the console has moved; read inside this window and the OLD port comes back. MEASURED as the pause the working tools need (gunnar console.rs, 2 s).

§sync_tail_maintenance_ms: u64

The last leg of an import: syncingmaintenanceonline. MEASURED as a sequence (clone_probe: “maintenance, syncing, maintenance, online”); the split of the 100–130 s between the two legs is not, so this is carved out of the sync range rather than added to it.

Implementations§

Source§

impl Timings

Source

pub fn reimage_observers(&self, seed: u64, tag: &str) -> (u64, u64)

The same re-image, as the two observers see it.

Returns (guest_uart_ms, ladder_wall_ms). They differ by two orders of magnitude and they are both right: the first is the guest’s own install, the second is everything the provider does around it. Reporting one number for “install” is what makes a 60-second bar unpassable and makes moving the bar look reasonable.

Trait Implementations§

Source§

impl Clone for Timings

Source§

fn clone(&self) -> Self

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 Copy for Timings

Source§

impl Debug for Timings

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for Timings

Source§

fn default() -> Self

Returns the “default value” for a type. 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> 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.