Skip to content

Commit c768a16

Browse files
committed
support getting stderr
1 parent c4ccfe3 commit c768a16

10 files changed

Lines changed: 87 additions & 32 deletions

File tree

coman/src/app/messages.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ pub enum CscsMsg {
4949
}
5050
#[derive(Debug, PartialEq)]
5151
pub enum JobMsg {
52-
ShowLog(usize),
53-
CloseLog,
52+
Show(usize),
53+
Switch,
54+
Close,
5455
}
5556
#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq, Ord, strum::Display)]
5657
pub enum View {

coman/src/app/model.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::{
2626
},
2727
cscs::{
2828
handlers::{cscs_login, cscs_system_set},
29-
ports::TreeAction,
29+
ports::{JobLogAction, TreeAction},
3030
},
3131
trace_dbg,
3232
util::ui::{draw_area_in_absolute, draw_area_in_absolute_fixed_height},
@@ -56,7 +56,7 @@ where
5656

5757
/// Triggers watching job logs
5858
/// sending None stops watching
59-
pub job_log_tx: mpsc::Sender<Option<usize>>,
59+
pub job_log_tx: mpsc::Sender<JobLogAction>,
6060

6161
/// Allows creating user events based on messages
6262
pub user_event_tx: mpsc::Sender<UserEvent>,
@@ -74,7 +74,7 @@ where
7474
bridge: TerminalBridge<T>,
7575
error_tx: mpsc::Sender<String>,
7676
select_system_tx: mpsc::Sender<()>,
77-
job_log_tx: mpsc::Sender<Option<usize>>,
77+
job_log_tx: mpsc::Sender<JobLogAction>,
7878
user_event_tx: mpsc::Sender<UserEvent>,
7979
file_tree_tx: mpsc::Sender<TreeAction>,
8080
) -> Self {
@@ -305,7 +305,7 @@ where
305305
}
306306
fn handle_job_msg(&mut self, msg: JobMsg) -> Option<Msg> {
307307
match msg {
308-
JobMsg::ShowLog(jobid) => {
308+
JobMsg::Show(jobid) => {
309309
if self.app.mounted(&Id::WorkloadList) {
310310
assert!(self.app.umount(&Id::WorkloadList).is_ok());
311311
}
@@ -319,11 +319,18 @@ where
319319
assert!(self.app.active(&Id::WorkloadLogs).is_ok());
320320
let job_log_tx = self.job_log_tx.clone();
321321
tokio::spawn(async move {
322-
job_log_tx.send(Some(jobid)).await.unwrap();
322+
job_log_tx.send(JobLogAction::Job(jobid)).await.unwrap();
323323
});
324324
None
325325
}
326-
JobMsg::CloseLog => {
326+
JobMsg::Switch => {
327+
let job_log_tx = self.job_log_tx.clone();
328+
tokio::spawn(async move {
329+
job_log_tx.send(JobLogAction::SwitchLog).await.unwrap();
330+
});
331+
None
332+
}
333+
JobMsg::Close => {
327334
if self.app.mounted(&Id::WorkloadLogs) {
328335
assert!(self.app.umount(&Id::WorkloadLogs).is_ok());
329336
}
@@ -338,7 +345,7 @@ where
338345
let job_log_tx = self.job_log_tx.clone();
339346
tokio::spawn(async move {
340347
// stopp polling for logs
341-
job_log_tx.send(None).await.unwrap();
348+
job_log_tx.send(JobLogAction::Stop).await.unwrap();
342349
});
343350
None
344351
}

coman/src/cli.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ pub enum CscsJobCommands {
6363
#[clap(alias("g"), about = "Get metadata for a specific job [aliases: g]")]
6464
Get { job_id: i64 },
6565
#[clap(about = "Get the stdout of a job")]
66-
Log { job_id: i64 },
66+
Log {
67+
#[clap(short, long, action, help = "whether to get stderr instead of stdout")]
68+
stderr: bool,
69+
job_id: i64,
70+
},
6771

6872
#[clap(alias("s"), about = "Submit a new compute job [aliases: s]")]
6973
Submit {

coman/src/components/toolbar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
},
99
trace_dbg,
1010
};
11-
const WORKLOAD_TOOLTIP: &str = "q: quit, Esc: close/back, l: logs, f: File view, x: menu, ?: help";
11+
const WORKLOAD_TOOLTIP: &str = "q: quit, Esc: close/back, l: logs, f: File view, x: menu, tab: switch view, ?: help";
1212
const FILETREE_TOOLTIP: &str = "q: quit, ↑↓: navigate,←→: collapse/expand, x: menu, ?: help";
1313

1414
#[derive(MockComponent)]

coman/src/components/workload_list.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Component<Msg, UserEvent> for WorkloadList {
7777
&& !self.jobs.is_empty()
7878
{
7979
let job = self.jobs[index].clone();
80-
return Some(Msg::Job(JobMsg::ShowLog(job.id)));
80+
return Some(Msg::Job(JobMsg::Show(job.id)));
8181
}
8282
CmdResult::None
8383
}

coman/src/components/workload_log.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,32 @@ use tuirealm::{
66
props::{Alignment, BorderType, Borders, Color, PropPayload, PropValue, TextSpan},
77
};
88

9-
use crate::{
10-
app::{
11-
messages::{JobMsg, Msg},
12-
user_events::{CscsEvent, UserEvent},
13-
},
14-
trace_dbg,
9+
use crate::app::{
10+
messages::{JobMsg, Msg},
11+
user_events::{CscsEvent, UserEvent},
1512
};
1613

1714
#[derive(MockComponent)]
1815
pub struct WorkloadLog {
1916
component: Textarea,
17+
stderr: bool,
2018
}
2119

2220
impl WorkloadLog {
2321
pub fn new() -> Self {
2422
Self {
2523
component: Textarea::default()
2624
.borders(Borders::default().modifiers(BorderType::Rounded).color(Color::Yellow))
27-
.title("Workload Log", Alignment::Center)
25+
.title("Workload Log (stdout)", Alignment::Center)
2826
.step(4),
27+
stderr: false,
2928
}
3029
}
3130
}
3231
impl Component<Msg, UserEvent> for WorkloadLog {
3332
fn on(&mut self, ev: tuirealm::Event<UserEvent>) -> Option<Msg> {
3433
let _ = match ev {
3534
Event::User(UserEvent::Cscs(CscsEvent::GotJobLog(log))) => {
36-
let _ = trace_dbg!("got log component");
37-
let log = trace_dbg!(log);
3835
self.attr(
3936
Attribute::Text,
4037
AttrValue::Payload(PropPayload::Vec(
@@ -51,8 +48,25 @@ impl Component<Msg, UserEvent> for WorkloadLog {
5148
Event::Keyboard(KeyEvent { code: Key::PageUp, .. }) => self.perform(Cmd::Scroll(Direction::Up)),
5249
Event::Keyboard(KeyEvent { code: Key::Home, .. }) => self.perform(Cmd::GoTo(Position::Begin)),
5350
Event::Keyboard(KeyEvent { code: Key::End, .. }) => self.perform(Cmd::GoTo(Position::End)),
51+
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
52+
self.stderr = !self.stderr;
53+
if self.stderr {
54+
self.attr(
55+
Attribute::Title,
56+
AttrValue::Title(("Workload Log (stderr)".to_owned(), Alignment::Center)),
57+
);
58+
} else {
59+
self.attr(
60+
Attribute::Title,
61+
AttrValue::Title(("Workload Log (stdout)".to_owned(), Alignment::Center)),
62+
);
63+
}
64+
// empty log view
65+
self.attr(Attribute::Text, AttrValue::Payload(PropPayload::Vec(vec![])));
66+
return Some(Msg::Job(JobMsg::Switch));
67+
}
5468
Event::Keyboard(KeyEvent { code: Key::Esc, .. }) => {
55-
return Some(Msg::Job(JobMsg::CloseLog));
69+
return Some(Msg::Job(JobMsg::Close));
5670
}
5771
_ => CmdResult::None,
5872
};

coman/src/cscs/cli.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ pub(crate) async fn cli_cscs_job_detail(
8787

8888
pub(crate) async fn cli_cscs_job_log(
8989
job_id: i64,
90+
stderr: bool,
9091
system: Option<String>,
9192
platform: Option<ComputePlatform>,
9293
) -> Result<()> {
93-
match cscs_job_log(job_id, system, platform).await {
94+
match cscs_job_log(job_id, stderr, system, platform).await {
9495
Ok(content) => {
9596
println!("{}", content);
9697
Ok(())

coman/src/cscs/handlers.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,12 @@ pub async fn cscs_job_details(
117117
}
118118
}
119119

120-
pub async fn cscs_job_log(job_id: i64, system: Option<String>, platform: Option<ComputePlatform>) -> Result<String> {
120+
pub async fn cscs_job_log(
121+
job_id: i64,
122+
stderr: bool,
123+
system: Option<String>,
124+
platform: Option<ComputePlatform>,
125+
) -> Result<String> {
121126
match get_access_token().await {
122127
Ok(access_token) => {
123128
let api_client = CscsApi::new(access_token.0, platform).unwrap();
@@ -127,9 +132,12 @@ pub async fn cscs_job_log(job_id: i64, system: Option<String>, platform: Option<
127132
if job.is_none() {
128133
return Err(eyre!("couldn't find job {}", job_id));
129134
}
130-
api_client
131-
.tail(current_system, PathBuf::from(job.unwrap().stdout), 100)
132-
.await
135+
let path = if stderr {
136+
PathBuf::from(job.unwrap().stderr)
137+
} else {
138+
PathBuf::from(job.unwrap().stdout)
139+
};
140+
api_client.tail(current_system, path, 100).await
133141
}
134142
Err(e) => Err(e),
135143
}

coman/src/cscs/ports.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,25 @@ impl PollAsync<UserEvent> for AsyncSelectSystemPort {
154154
}
155155
}
156156

157+
pub enum JobLogAction {
158+
Job(usize),
159+
SwitchLog,
160+
Stop,
161+
}
162+
157163
/// This port handles polling the logs of a CSCS job
158164
pub(crate) struct AsyncJobLogPort {
159-
receiver: mpsc::Receiver<Option<usize>>,
165+
receiver: mpsc::Receiver<JobLogAction>,
160166
current_job: Option<usize>,
167+
stderr: bool,
161168
}
162169

163170
impl AsyncJobLogPort {
164-
pub fn new(receiver: mpsc::Receiver<Option<usize>>) -> Self {
171+
pub fn new(receiver: mpsc::Receiver<JobLogAction>) -> Self {
165172
Self {
166173
receiver,
167174
current_job: None,
175+
stderr: false,
168176
}
169177
}
170178
}
@@ -176,11 +184,21 @@ impl PollAsync<UserEvent> for AsyncJobLogPort {
176184
}
177185
if !self.receiver.is_empty() {
178186
if let Some(val) = self.receiver.recv().await {
179-
self.current_job = val;
187+
match val {
188+
JobLogAction::Job(jobid) => {
189+
self.current_job = Some(jobid);
190+
}
191+
JobLogAction::SwitchLog => {
192+
self.stderr = !self.stderr;
193+
}
194+
JobLogAction::Stop => {
195+
self.current_job = None;
196+
}
197+
}
180198
}
181199
Ok(Some(Event::None))
182200
} else if let Some(job_id) = self.current_job {
183-
match cscs_job_log(job_id as i64, None, None).await {
201+
match cscs_job_log(job_id as i64, self.stderr, None, None).await {
184202
Ok(log) => {
185203
let log = trace_dbg!(log);
186204
Ok(Some(Event::User(UserEvent::Cscs(CscsEvent::GotJobLog(log)))))

coman/src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ async fn main() -> Result<()> {
6363
cli::CscsCommands::Job { command } => match command {
6464
cli::CscsJobCommands::List => cli_cscs_job_list(system, platform).await?,
6565
cli::CscsJobCommands::Get { job_id } => cli_cscs_job_detail(job_id, system, platform).await?,
66-
cli::CscsJobCommands::Log { job_id } => cli_cscs_job_log(job_id, system, platform).await?,
66+
cli::CscsJobCommands::Log { job_id, stderr } => {
67+
cli_cscs_job_log(job_id, stderr, system, platform).await?
68+
}
6769
cli::CscsJobCommands::Submit {
6870
script_file,
6971
image,

0 commit comments

Comments
 (0)