From 9f5bf9975d3e239435600b1c3d4c7abbbdb9de14 Mon Sep 17 00:00:00 2001 From: Marcus Behrendt Date: Fri, 18 Nov 2022 19:48:43 +0100 Subject: [PATCH] feat(container-log-page): Hide spinner for zero length logs --- src/view/container/log_page.rs | 99 ++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 41 deletions(-) diff --git a/src/view/container/log_page.rs b/src/view/container/log_page.rs index f7f778c05..1ca70d034 100644 --- a/src/view/container/log_page.rs +++ b/src/view/container/log_page.rs @@ -5,6 +5,8 @@ use std::collections::VecDeque; use std::io::BufWriter; use std::io::Write; use std::mem; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; use ashpd::desktop::file_chooser::Choice; use ashpd::desktop::file_chooser::SaveFileRequest; @@ -349,13 +351,13 @@ mod imp { Some("status"), clone!(@weak obj => move |container, _| { if container.status() == model::ContainerStatus::Running { - obj.follow_log_again(); + obj.follow_log(); } }), ); } - obj.follow_log(); + obj.init_log(); } fn dispose(&self) { @@ -442,46 +444,60 @@ impl LogPage { imp.prev_adj.replace(adj.value()); } - fn follow_log(&self) { + fn init_log(&self) { if let Some(container) = self.container().as_ref().and_then(model::Container::api) { let mut perform = MarkupPerform::default(); - utils::run_stream( + utils::run_stream_with_finish_handler( container, move |container| { container - .logs(&basic_opts_builder(true, true).tail("512").build()) + .logs(&basic_opts_builder(false, true).tail("512").build()) .boxed() }, clone!(@weak self as obj => @default-return glib::Continue(false), move |result| { obj.imp().stack.set_visible_child_name("loaded"); obj.append_line(result, &mut perform) }), + clone!(@weak self as obj => move || { + obj.imp().stack.set_visible_child_name("loaded"); + obj.follow_log(); + }), ); } } - fn follow_log_again(&self) { + fn follow_log(&self) { if let Some(container) = self.container().as_ref().and_then(model::Container::api) { - let mut perform = MarkupPerform::default(); - - let log_timestamps = self.imp().log_timestamps.borrow(); - let opts = if !log_timestamps.is_empty() { - let since = - glib::DateTime::from_iso8601(&log_timestamps[log_timestamps.len() - 1], None) - .unwrap() - .to_unix() - + 1; - basic_opts_builder(true, true).since(since.to_string()) - } else { - basic_opts_builder(true, true) + let timestamps = self.imp().log_timestamps.borrow(); + let mut iter = timestamps.iter().rev(); + + let opts = basic_opts_builder(true, true); + let (opts, skip) = match iter.next() { + Some(last) => ( + opts.since( + glib::DateTime::from_iso8601(last, None) + .unwrap() + .to_unix() + .to_string(), + ), + AtomicUsize::new(iter.take_while(|t| *t == last).count() + 1), + ), + None => (opts, AtomicUsize::new(0)), }; + let mut perform = MarkupPerform::default(); + utils::run_stream( container, move |container| container.logs(&opts.build()).boxed(), - clone!(@weak self as obj => @default-return glib::Continue(false), move |result| { - obj.append_line(result, &mut perform) + clone!(@weak self as obj => @default-return glib::Continue(false), move |result: podman::Result| { + if skip.load(Ordering::Relaxed) == 0 { + obj.append_line(result, &mut perform) + } else { + skip.fetch_sub(1, Ordering::Relaxed); + glib::Continue(true) + } }), ); } @@ -513,30 +529,31 @@ impl LogPage { let imp = self.imp(); let line_buffer = perform.decode(&line); + let (timestamp, log_message) = line_buffer.split_once(' ').unwrap(); - if let Some((timestamp, log_message)) = line_buffer.split_once(' ') { - imp.fetch_until.get_or_init(|| timestamp.to_owned()); - - let source_buffer = &*imp.source_buffer; - source_buffer.insert_markup( - &mut if at_end { - imp.source_buffer.end_iter() - } else { - imp.source_buffer.start_iter() - }, - &if source_buffer.start_iter() == source_buffer.end_iter() { - Cow::Borrowed(log_message) - } else { - Cow::Owned(format!("\n{log_message}")) - }, - ); + imp.fetch_until.get_or_init(|| timestamp.to_owned()); - let mut timestamps = imp.log_timestamps.borrow_mut(); - if at_end { - timestamps.push_back(timestamp.to_owned()); + let source_buffer = &*imp.source_buffer; + source_buffer.insert_markup( + &mut if at_end { + imp.source_buffer.end_iter() } else { - timestamps.push_front(timestamp.to_owned()); - } + imp.source_buffer.start_iter() + }, + &if source_buffer.start_iter() == source_buffer.end_iter() { + Cow::Borrowed(log_message) + } else if at_end { + Cow::Owned(format!("\n{log_message}")) + } else { + Cow::Owned(format!("{log_message}\n")) + }, + ); + + let mut timestamps = imp.log_timestamps.borrow_mut(); + if at_end { + timestamps.push_back(timestamp.to_owned()); + } else { + timestamps.push_front(timestamp.to_owned()); } }