mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
make progress updates fail gracefully on server queue full
Progress updates can come at a right too high for the renderer to keep up, so instead of deadlocking, we discard update messages that are too frequent.
This commit is contained in:
parent
3ef2dae2f0
commit
3f962b6bb0
3 changed files with 37 additions and 35 deletions
|
|
@ -81,7 +81,7 @@ pub(crate) enum Opcode {
|
|||
/// raise a progress bar
|
||||
StartProgress,
|
||||
/// update the progress bar
|
||||
UpdateProgress,
|
||||
DoUpdateProgress,
|
||||
/// lower a progress bar
|
||||
StopProgress,
|
||||
/// update a dynamic notification's text
|
||||
|
|
@ -99,7 +99,6 @@ pub(crate) enum Opcode {
|
|||
// box because it's a convenience routine used by "everyone"; password boxes are always handled within
|
||||
// a given secured server so that the attack surface for these do not extend into the modals boundary.
|
||||
InitiateOp,
|
||||
DoUpdateProgress,
|
||||
FinishProgress,
|
||||
|
||||
TextEntryReturn,
|
||||
|
|
|
|||
|
|
@ -111,9 +111,17 @@ impl Modals {
|
|||
/// but, progress updates are meant to be fast and frequent, and generally if a progress bar shows
|
||||
/// something whacky it's not going to affect a security outcome
|
||||
pub fn update_progress(&self, current: u32) -> Result<(), xous::Error> {
|
||||
send_message(self.conn,
|
||||
Message::new_scalar(Opcode::UpdateProgress.to_usize().unwrap(), current as usize, 0, 0, 0)
|
||||
).expect("couldn't update progress");
|
||||
match xous::try_send_message(self.conn,
|
||||
Message::new_scalar(Opcode::DoUpdateProgress.to_usize().unwrap(), current as usize, 0, 0, 0)
|
||||
) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
log::warn!("update_progress failed with {:?}, skipping request", e);
|
||||
// most likely issue is that the server queue is overfull because too many progress updates were sent
|
||||
// sleep the sending thread to rate-limit requests, while discarding the current request.
|
||||
xous::yield_slice()
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -224,12 +224,6 @@ fn xmain() -> ! {
|
|||
Message::new_scalar(Opcode::InitiateOp.to_usize().unwrap(), 0, 0, 0, 0)
|
||||
).expect("couldn't initiate UX op");
|
||||
},
|
||||
Some(Opcode::UpdateProgress) => msg_scalar_unpack!(msg, current, _, _, _, {
|
||||
send_message(
|
||||
renderer_cid,
|
||||
Message::new_scalar(Opcode::DoUpdateProgress.to_usize().unwrap(), current, 0, 0, 0)
|
||||
).expect("couldn't update progress bar");
|
||||
}),
|
||||
Some(Opcode::StopProgress) => msg_scalar_unpack!(msg, t0, t1, t2, t3, {
|
||||
let token = [t0 as u32, t1 as u32, t2 as u32, t3 as u32];
|
||||
if token != token_lock.unwrap_or(default_nonce) {
|
||||
|
|
@ -289,6 +283,30 @@ fn xmain() -> ! {
|
|||
Message::new_scalar(Opcode::DoCloseDynamicNotification.to_usize().unwrap(), 0, 0, 0, 0)
|
||||
).expect("couldn't close dynamic notification");
|
||||
}),
|
||||
// this got promoted to an external API during the deferred response refactor to eliminate an intermediate state
|
||||
Some(Opcode::DoUpdateProgress) => msg_scalar_unpack!(msg, current, _, _, _, {
|
||||
let new_percentage = compute_checked_percentage(
|
||||
current as u32, start_work, end_work);
|
||||
log::trace!("percentage: {}, current: {}, start: {}, end: {}", new_percentage, current, start_work, end_work);
|
||||
if new_percentage != last_percentage {
|
||||
last_percentage = new_percentage;
|
||||
progress_action.set_state(last_percentage);
|
||||
#[cfg(feature="tts")]
|
||||
{
|
||||
if tt.elapsed_ms() - last_tick > TICK_INTERVAL {
|
||||
tts.tts_blocking(t!("progress.increment", xous::LANG)).unwrap();
|
||||
last_tick = tt.elapsed_ms();
|
||||
}
|
||||
}
|
||||
renderer_modal.modify(
|
||||
Some(ActionType::Slider(progress_action)),
|
||||
None, false,
|
||||
None, false, None
|
||||
);
|
||||
renderer_modal.redraw();
|
||||
xous::yield_slice(); // give time for the GAM to redraw
|
||||
}
|
||||
}),
|
||||
|
||||
// ------------------ INTERNAL APIS --------------------
|
||||
Some(Opcode::InitiateOp) => {
|
||||
|
|
@ -394,7 +412,7 @@ fn xmain() -> ! {
|
|||
#[cfg(feature="tts")]
|
||||
tts.tts_simple(text.as_str().unwrap()).unwrap();
|
||||
bot_text.push_str(text.as_str().unwrap());
|
||||
}
|
||||
}
|
||||
let mut gutter = gam::modal::Notification::new(
|
||||
renderer_cid,
|
||||
Opcode::Gutter.to_u32().unwrap()
|
||||
|
|
@ -414,29 +432,6 @@ fn xmain() -> ! {
|
|||
}
|
||||
}
|
||||
},
|
||||
Some(Opcode::DoUpdateProgress) => msg_scalar_unpack!(msg, current, _, _, _, {
|
||||
let new_percentage = compute_checked_percentage(
|
||||
current as u32, start_work, end_work);
|
||||
log::trace!("percentage: {}, current: {}, start: {}, end: {}", new_percentage, current, start_work, end_work);
|
||||
if new_percentage != last_percentage {
|
||||
last_percentage = new_percentage;
|
||||
progress_action.set_state(last_percentage);
|
||||
#[cfg(feature="tts")]
|
||||
{
|
||||
if tt.elapsed_ms() - last_tick > TICK_INTERVAL {
|
||||
tts.tts_blocking(t!("progress.increment", xous::LANG)).unwrap();
|
||||
last_tick = tt.elapsed_ms();
|
||||
}
|
||||
}
|
||||
renderer_modal.modify(
|
||||
Some(ActionType::Slider(progress_action)),
|
||||
None, false,
|
||||
None, false, None
|
||||
);
|
||||
renderer_modal.redraw();
|
||||
xous::yield_slice(); // give time for the GAM to redraw
|
||||
}
|
||||
}),
|
||||
Some(Opcode::FinishProgress) => {
|
||||
renderer_modal.gam.relinquish_focus().unwrap();
|
||||
op = RendererState::None;
|
||||
|
|
|
|||
Loading…
Reference in a new issue