Avoid redundant metrics when rewinding

This commit is contained in:
Héctor Ramón Jiménez 2025-04-20 21:50:12 +02:00
parent 5b649541b6
commit 7c6155242c
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
6 changed files with 93 additions and 44 deletions

View file

@ -99,9 +99,10 @@ enum Action {
Forward(mpsc::Sender<Command>), Forward(mpsc::Sender<Command>),
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum Command { pub enum Command {
RewindTo { message: usize }, RewindTo { message: usize },
GoLive,
} }
#[tokio::main] #[tokio::main]

View file

@ -36,6 +36,14 @@ impl Connection {
let _ = commands.send(client::Command::RewindTo { message }).await; let _ = commands.send(client::Command::RewindTo { message }).await;
} }
} }
pub fn go_live<'a>(&self) -> impl Future<Output = ()> + 'a {
let commands = self.commands.clone();
async move {
let _ = commands.send(client::Command::GoLive).await;
}
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -128,14 +136,19 @@ pub fn run() -> impl Stream<Item = Event> {
let mut last_message_number = None; let mut last_message_number = None;
while let Some(command) = command_receiver.recv().await { while let Some(command) = command_receiver.recv().await {
let client::Command::RewindTo { message } = command; match command {
client::Command::RewindTo { message } => {
if Some(message) == last_message_number {
continue;
}
if Some(message) == last_message_number { last_message_number = Some(message);
continue; }
client::Command::GoLive => {
last_message_number = None;
}
} }
last_message_number = Some(message);
let _ = let _ =
send(&mut writer, command).await.inspect_err(|error| { send(&mut writer, command).await.inspect_err(|error| {
log::error!("Error when sending command: {error}") log::error!("Error when sending command: {error}")

View file

@ -21,6 +21,15 @@ pub enum Primitive {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Command { pub enum Command {
RewindTo { message: usize }, RewindTo { message: usize },
GoLive,
}
pub fn enable() {
internal::enable();
}
pub fn disable() {
internal::disable();
} }
pub fn init(name: &str) { pub fn init(name: &str) {
@ -91,10 +100,6 @@ pub fn time_with<T>(name: impl Into<String>, f: impl FnOnce() -> T) -> T {
result result
} }
pub fn skip_next_timing() {
internal::skip_next_timing();
}
pub fn commands() -> Subscription<Command> { pub fn commands() -> Subscription<Command> {
internal::commands() internal::commands()
} }
@ -139,7 +144,7 @@ mod internal {
if let Some(palette) = if let Some(palette) =
LAST_PALETTE.read().expect("Read last palette").as_ref() LAST_PALETTE.read().expect("Read last palette").as_ref()
{ {
BEACON.log(client::Event::ThemeChanged(*palette)); log(client::Event::ThemeChanged(*palette));
} }
Ok(()) Ok(())
@ -154,18 +159,18 @@ mod internal {
if LAST_PALETTE.read().expect("Read last palette").as_ref() if LAST_PALETTE.read().expect("Read last palette").as_ref()
!= Some(&palette) != Some(&palette)
{ {
BEACON.log(client::Event::ThemeChanged(palette)); log(client::Event::ThemeChanged(palette));
*LAST_PALETTE.write().expect("Write last palette") = Some(palette); *LAST_PALETTE.write().expect("Write last palette") = Some(palette);
} }
} }
pub fn tasks_spawned(amount: usize) { pub fn tasks_spawned(amount: usize) {
BEACON.log(client::Event::CommandsSpawned(amount)); log(client::Event::CommandsSpawned(amount));
} }
pub fn subscriptions_tracked(amount: usize) { pub fn subscriptions_tracked(amount: usize) {
BEACON.log(client::Event::SubscriptionsTracked(amount)); log(client::Event::SubscriptionsTracked(amount));
} }
pub fn boot() -> Span { pub fn boot() -> Span {
@ -193,7 +198,7 @@ mod internal {
message message
}; };
BEACON.log(client::Event::MessageLogged { number, message }); log(client::Event::MessageLogged { number, message });
span span
} }
@ -230,8 +235,12 @@ mod internal {
span(span::Stage::Custom(name.into())) span(span::Stage::Custom(name.into()))
} }
pub fn skip_next_timing() { pub fn enable() {
SKIP_NEXT_SPAN.store(true, atomic::Ordering::Relaxed); ENABLED.store(true, atomic::Ordering::Relaxed);
}
pub fn disable() {
ENABLED.store(false, atomic::Ordering::Relaxed);
} }
pub fn commands() -> Subscription<Command> { pub fn commands() -> Subscription<Command> {
@ -243,6 +252,7 @@ mod internal {
client::Command::RewindTo { message } => { client::Command::RewindTo { message } => {
Command::RewindTo { message } Command::RewindTo { message }
} }
client::Command::GoLive => Command::GoLive,
}; };
Some((command, receiver)) Some((command, receiver))
@ -253,7 +263,7 @@ mod internal {
} }
fn span(span: span::Stage) -> Span { fn span(span: span::Stage) -> Span {
BEACON.log(client::Event::SpanStarted(span.clone())); log(client::Event::SpanStarted(span.clone()));
Span { Span {
span, span,
@ -271,6 +281,12 @@ mod internal {
} }
} }
fn log(event: client::Event) {
if ENABLED.load(atomic::Ordering::Relaxed) {
BEACON.log(event);
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Span { pub struct Span {
span: span::Stage, span: span::Stage,
@ -279,14 +295,7 @@ mod internal {
impl Span { impl Span {
pub fn finish(self) { pub fn finish(self) {
if SKIP_NEXT_SPAN.fetch_and(false, atomic::Ordering::Relaxed) { log(client::Event::SpanFinished(self.span, self.start.elapsed()));
return;
}
BEACON.log(client::Event::SpanFinished(
self.span,
self.start.elapsed(),
));
} }
} }
@ -297,7 +306,7 @@ mod internal {
static NAME: RwLock<String> = RwLock::new(String::new()); static NAME: RwLock<String> = RwLock::new(String::new());
static LAST_UPDATE: AtomicUsize = AtomicUsize::new(0); static LAST_UPDATE: AtomicUsize = AtomicUsize::new(0);
static LAST_PALETTE: RwLock<Option<theme::Palette>> = RwLock::new(None); static LAST_PALETTE: RwLock<Option<theme::Palette>> = RwLock::new(None);
static SKIP_NEXT_SPAN: AtomicBool = AtomicBool::new(false); static ENABLED: AtomicBool = AtomicBool::new(true);
} }
#[cfg(any(not(feature = "enable"), target_arch = "wasm32"))] #[cfg(any(not(feature = "enable"), target_arch = "wasm32"))]
@ -309,6 +318,9 @@ mod internal {
use std::io; use std::io;
pub fn enable() {}
pub fn disable() {}
pub fn init(_name: &str) {} pub fn init(_name: &str) {}
pub fn toggle_comet() -> Result<(), io::Error> { pub fn toggle_comet() -> Result<(), io::Error> {
@ -361,8 +373,6 @@ mod internal {
Span Span
} }
pub fn skip_next_timing() {}
pub fn commands() -> Subscription<Command> { pub fn commands() -> Subscription<Command> {
Subscription::none() Subscription::none()
} }

View file

@ -17,6 +17,6 @@ workspace = true
time-travel = ["iced_program/time-travel"] time-travel = ["iced_program/time-travel"]
[dependencies] [dependencies]
iced_debug.workspace = true
iced_program.workspace = true iced_program.workspace = true
iced_widget.workspace = true iced_widget.workspace = true
iced_debug.workspace = true

View file

@ -116,7 +116,7 @@ where
mode: Mode, mode: Mode,
show_notification: bool, show_notification: bool,
rewind: Option<P::State>, rewind: Option<P::State>,
log: Vec<P::Message>, messages: Vec<P::Message>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -150,7 +150,7 @@ where
mode: Mode::None, mode: Mode::None,
show_notification: true, show_notification: true,
rewind: None, rewind: None,
log: Vec::new(), messages: Vec::new(),
}, },
executor::spawn_blocking(|mut sender| { executor::spawn_blocking(|mut sender| {
thread::sleep(seconds(2)); thread::sleep(seconds(2));
@ -254,13 +254,13 @@ where
} }
}, },
Event::Program(message) => { Event::Program(message) => {
if self.rewind.is_some() {
return Task::none();
}
#[cfg(feature = "time-travel")] #[cfg(feature = "time-travel")]
{ {
self.log.push(message.clone()); self.messages.push(message.clone());
}
if self.rewind.is_some() {
debug::enable();
} }
let span = debug::update(&message); let span = debug::update(&message);
@ -268,6 +268,10 @@ where
debug::tasks_spawned(task.units()); debug::tasks_spawned(task.units());
span.finish(); span.finish();
if self.rewind.is_some() {
debug::disable();
}
task.map(Event::Program) task.map(Event::Program)
} }
Event::Command(command) => { Event::Command(command) => {
@ -277,24 +281,33 @@ where
{ {
let (mut state, _) = program.boot(); let (mut state, _) = program.boot();
if message < self.log.len() { if message < self.messages.len() {
// TODO: Run concurrently (?) // TODO: Run concurrently (?)
for message in &self.log[0..message] { for message in &self.messages[0..message] {
let _ = program let _ = program
.update(&mut state, message.clone()); .update(&mut state, message.clone());
} }
} }
self.rewind = Some(state); self.rewind = Some(state);
debug::disable();
} }
#[cfg(not(feature = "time-travel"))] #[cfg(not(feature = "time-travel"))]
let _ = message; let _ = message;
} }
debug::Command::GoLive => {
#[cfg(feature = "time-travel")]
{
self.rewind = None;
debug::enable();
}
}
} }
Task::none() Task::none()
} }
Event::Discard => Task::none(),
} }
} }
@ -305,7 +318,16 @@ where
) -> Element<'_, Event<P>, P::Theme, P::Renderer> { ) -> Element<'_, Event<P>, P::Theme, P::Renderer> {
let state = self.rewind.as_ref().unwrap_or(&self.state); let state = self.rewind.as_ref().unwrap_or(&self.state);
let view = program.view(state, window).map(Event::Program); let view = {
let view = program.view(state, window);
if self.rewind.is_some() {
view.map(|_| Event::Discard)
} else {
view.map(Event::Program)
}
};
let theme = program.theme(state, window); let theme = program.theme(state, window);
let derive_theme = move || { let derive_theme = move || {
@ -455,6 +477,7 @@ where
Message(Message), Message(Message),
Program(P::Message), Program(P::Message),
Command(debug::Command), Command(debug::Command),
Discard,
} }
impl<P> fmt::Debug for Event<P> impl<P> fmt::Debug for Event<P>
@ -466,6 +489,7 @@ where
Self::Message(message) => message.fmt(f), Self::Message(message) => message.fmt(f),
Self::Program(message) => message.fmt(f), Self::Program(message) => message.fmt(f),
Self::Command(command) => command.fmt(f), Self::Command(command) => command.fmt(f),
Self::Discard => f.write_str("Discard"),
} }
} }
} }
@ -477,9 +501,10 @@ where
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self { match self {
Event::Message(message) => Event::Message(message.clone()), Self::Message(message) => Self::Message(message.clone()),
Event::Program(message) => Event::Program(message.clone()), Self::Program(message) => Self::Program(message.clone()),
Event::Command(command) => Event::Command(*command), Self::Command(command) => Self::Command(*command),
Self::Discard => Self::Discard,
} }
} }
} }

View file

@ -535,7 +535,7 @@ pub use alignment::Vertical::{Bottom, Top};
pub mod debug { pub mod debug {
//! Debug your applications. //! Debug your applications.
pub use iced_debug::{Span, skip_next_timing, time, time_with}; pub use iced_debug::{Span, time, time_with};
} }
pub mod task { pub mod task {