fix(install): kick scanner post-install so Launch button appears immediately
After install completes, the async-spawn wrapper wrote state=Running
but the skeletal install-time manifest (interfaces: None) persisted
until the next scheduled 60s scan. The frontend saw state=running but
hasUI=false and hid the Launch button for up to a full minute.
Add a shared Notify/watch pair between RpcHandler and the scan loop:
- scan_kick (Notify): scan loop selects! between the 60s interval
and this notify, running immediately on either.
- scan_tick (watch<u64>): scan loop bumps the counter after each
completed scan so callers can await completion.
Install and update success paths now call kick_scanner_and_wait before
flipping to Running. The scan merges via merge_preserving_transitional
(state stays Installing/Updating, manifest refreshed from live podman
with interfaces.main.ui populated from real port bindings). 2s timeout
falls back to pre-fix behavior on slow podman — no regression.
This commit is contained in:
@@ -87,6 +87,15 @@ pub struct RpcHandler {
|
||||
/// Our own Ed25519 pubkey hex — needed by ContentRef senders for cap scoping
|
||||
/// and by ContentRef receivers to request caps scoped to themselves.
|
||||
pub(crate) self_pubkey_hex: Arc<tokio::sync::RwLock<Option<String>>>,
|
||||
/// Kick the package scanner to run immediately (bypassing the 60s interval).
|
||||
/// Used by install/update success paths so the fresh manifest (with populated
|
||||
/// `interfaces.main.ui`) lands before we flip state to Running — closes the
|
||||
/// "Launch button is missing for up to 60s after install" UX gap.
|
||||
pub(crate) scan_kick: Arc<tokio::sync::Notify>,
|
||||
/// Monotonic counter incremented by the scan loop after each completed scan.
|
||||
/// Install/update success paths subscribe to this to know when a kicked scan
|
||||
/// has actually finished before flipping to the terminal state.
|
||||
pub(crate) scan_tick: Arc<tokio::sync::watch::Sender<u64>>,
|
||||
}
|
||||
|
||||
impl RpcHandler {
|
||||
@@ -144,6 +153,8 @@ impl RpcHandler {
|
||||
transport_router: Arc::new(tokio::sync::RwLock::new(None)),
|
||||
blob_store: Arc::new(tokio::sync::RwLock::new(None)),
|
||||
self_pubkey_hex: Arc::new(tokio::sync::RwLock::new(None)),
|
||||
scan_kick: Arc::new(tokio::sync::Notify::new()),
|
||||
scan_tick: Arc::new(tokio::sync::watch::channel(0u64).0),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -184,6 +195,21 @@ impl RpcHandler {
|
||||
Arc::clone(&self.mesh_service)
|
||||
}
|
||||
|
||||
/// Shared Notify handle the package-scanner loop waits on (in addition to
|
||||
/// its periodic tick). Install/update success paths call `notify_one()` to
|
||||
/// trigger an immediate scan so the fresh manifest lands before we flip to
|
||||
/// the terminal Running state.
|
||||
pub fn scan_kick(&self) -> Arc<tokio::sync::Notify> {
|
||||
Arc::clone(&self.scan_kick)
|
||||
}
|
||||
|
||||
/// Sender half of the scan-completion watch channel. The scanner bumps this
|
||||
/// counter after every finished scan; install/update wait for an advance
|
||||
/// after kicking so they know the fresh manifest has landed.
|
||||
pub fn scan_tick(&self) -> Arc<tokio::sync::watch::Sender<u64>> {
|
||||
Arc::clone(&self.scan_tick)
|
||||
}
|
||||
|
||||
fn cookie_suffix_for_request(&self, headers: &hyper::header::HeaderMap) -> &'static str {
|
||||
// Only set Secure flag when the original request was over HTTPS.
|
||||
// Nginx sends X-Forwarded-Proto: https for HTTPS connections.
|
||||
|
||||
Reference in New Issue
Block a user