@@ -23,6 +23,7 @@ use crate::{JobId, JobTaskCount, WorkerId};
2323use chrono:: { DateTime , Local , SubsecRound , Utc } ;
2424use core:: time:: Duration ;
2525use humantime:: format_duration;
26+ use std:: borrow:: Cow ;
2627
2728use std:: path:: Path ;
2829use std:: time:: SystemTime ;
@@ -169,12 +170,12 @@ impl CliOutput {
169170 . iter ( )
170171 . filter_map ( |t : & JobTaskInfo | match & t. state {
171172 JobTaskState :: Failed {
172- started_data : StartedTaskData { worker_id , .. } ,
173+ started_data : StartedTaskData { worker_ids , .. } ,
173174 error,
174175 ..
175176 } => Some ( vec ! [
176177 t. task_id. cell( ) ,
177- format_worker ( * worker_id , worker_map) . cell( ) ,
178+ format_workers ( worker_ids , worker_map) . cell( ) ,
178179 error. to_owned( ) . cell( ) . foreground_color( Some ( Color :: Red ) ) ,
179180 ] ) ,
180181 _ => None ,
@@ -573,9 +574,9 @@ impl Output for CliOutput {
573574 job_rows. append ( & mut vec ! [
574575 task. task_id. cell( ) . justify( Justify :: Right ) ,
575576 task_status_to_cell( get_task_status( & task. state) ) ,
576- match task. state. get_worker ( ) {
577- Some ( worker ) => format_worker ( worker , & worker_map) ,
578- _ => "" ,
577+ match task. state. get_workers ( ) {
578+ Some ( workers ) => format_workers ( workers , & worker_map) ,
579+ _ => "" . into ( ) ,
579580 }
580581 . cell( ) ,
581582 multiline_cell( vec![
@@ -960,6 +961,9 @@ fn task_status_to_cell(status: Status) -> CellStruct {
960961}
961962
962963fn format_resource_request ( rq : & ResourceRequest ) -> String {
964+ if rq. n_nodes > 0 {
965+ return format ! ( "nodes: {}" , rq. n_nodes) ;
966+ }
963967 let mut result = format_cpu_request ( & rq. cpus ) ;
964968 for grq in & rq. generic {
965969 result. push_str ( & format ! ( "\n {}: {}" , grq. resource, grq. amount) )
@@ -987,14 +991,15 @@ pub fn format_job_workers(tasks: &[JobTaskInfo], worker_map: &WorkerMap) -> Stri
987991 // BTreeSet is used to both filter duplicates and keep a stable order
988992 let worker_set: BTreeSet < _ > = tasks
989993 . iter ( )
990- . filter_map ( |task| task. state . get_worker ( ) )
994+ . filter_map ( |task| task. state . get_workers ( ) )
995+ . flatten ( )
991996 . collect ( ) ;
992997 let worker_count = worker_set. len ( ) ;
993998
994999 let mut result = worker_set
9951000 . into_iter ( )
9961001 . take ( MAX_DISPLAYED_WORKERS )
997- . map ( |id| format_worker ( id, worker_map) )
1002+ . map ( |id| format_worker ( * id, worker_map) )
9981003 . collect :: < Vec < _ > > ( )
9991004 . join ( ", " ) ;
10001005
@@ -1012,6 +1017,21 @@ fn format_worker(id: WorkerId, worker_map: &WorkerMap) -> &str {
10121017 . unwrap_or_else ( || "N/A" )
10131018}
10141019
1020+ fn format_workers < ' a > ( ids : & [ WorkerId ] , worker_map : & ' a WorkerMap ) -> Cow < ' a , str > {
1021+ if ids. len ( ) == 1 {
1022+ format_worker ( ids[ 0 ] , worker_map) . into ( )
1023+ } else {
1024+ assert ! ( !ids. is_empty( ) ) ;
1025+ let mut result = String :: new ( ) ;
1026+ //result.push_str(format_worker(ids[0], worker_map));
1027+ for id in ids {
1028+ result. push_str ( format_worker ( * id, worker_map) ) ;
1029+ result. push ( '\n' ) ;
1030+ }
1031+ result. into ( )
1032+ }
1033+ }
1034+
10151035fn get_task_time ( state : & JobTaskState ) -> ( Option < DateTime < Utc > > , Option < DateTime < Utc > > ) {
10161036 match state {
10171037 JobTaskState :: Canceled {
0 commit comments