From 1c518e9754d9b754c9f0a2a525d6204ab2cb769a 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 | 120 ++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/src/view/container/log_page.rs b/src/view/container/log_page.rs index 2719495c6..087471421 100644 --- a/src/view/container/log_page.rs +++ b/src/view/container/log_page.rs @@ -254,13 +254,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) { @@ -327,46 +327,69 @@ 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, mut skip) = match iter.next() { + Some(last) => ( + opts.since( + glib::DateTime::from_iso8601(last, None) + .unwrap() + .to_unix() + .to_string(), + ), + 1 + iter.take_while(|t| *t == last).count(), + ), + None => (opts, 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 == 0 { + obj.append_line(result, &mut perform) + } else { + glib::Continue( + if let Some(line) = obj.foo(result) { + if perform.decode(&line) { + perform.move_out_buffer(); + skip -= 1; + } + true + } else { + true + }, + ) + } }), ); } @@ -394,34 +417,51 @@ impl LogPage { }) } + fn foo(&self, result: podman::Result) -> Option> { + match result { + Ok(line) => Some(Vec::from(line)), + Err(e) => { + log::warn!("Stopping container log stream due to error: {e}"); + utils::show_error_toast( + self.upcast_ref(), + &gettext("Error while following log"), + &e.to_string(), + ); + None + } + } + } + fn insert(&self, line: Vec, perform: &mut MarkupPerform, at_end: bool) { let imp = self.imp(); if perform.decode(&line) { let line_buffer = perform.move_out_buffer(); - if let Some((timestamp, log_message)) = line_buffer.split_once(' ') { - imp.fetch_until.get_or_init(|| timestamp.to_owned()); + let (timestamp, log_message) = line_buffer.split_once(' ').unwrap(); - 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!("{}\n", log_message)) + }, + ); + + let mut timestamps = imp.log_timestamps.borrow_mut(); + if at_end { + timestamps.push_back(timestamp.to_owned()); + } else { + timestamps.push_front(timestamp.to_owned()); } } }