Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(container-log-page): Hide spinner for zero length logs #434

Merged
merged 2 commits into from
Mar 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 59 additions & 42 deletions src/view/container/log_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -253,7 +255,7 @@ mod imp {
.margin_end(6)
.build();
renderer_timestamps.connect_query_data(clone!(@weak obj => move |renderer, _, line| {
let log_timestamps = obj.imp().log_timestamps.borrow_mut();
let log_timestamps = obj.imp().log_timestamps.borrow();
if let Some(timestamp) = log_timestamps.get(line as usize) {
let date_time = format!(
"<span foreground=\"#865e3c\">{timestamp}</span>",
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<podman::conn::TtyChunk>| {
if skip.load(Ordering::Relaxed) == 0 {
obj.append_line(result, &mut perform)
} else {
skip.fetch_sub(1, Ordering::Relaxed);
glib::Continue(true)
}
}),
);
}
Expand Down Expand Up @@ -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());
}
}

Expand Down