summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Aaron Murphy <mmstickman@gmail.com>2017-01-15 20:01:19 -0500
committerMichael Aaron Murphy <mmstickman@gmail.com>2017-01-15 20:21:07 -0500
commitc25d34a14cbabf81d719a24dd574be02a6c854d2 (patch)
treebad0ed8696e1bee43b6b7268c4821da7e9b9ee13
parentb5e61d5f222cb46f068f9946fc1be188f744e5b0 (diff)
0.10.3: Implement --joblog-8601 Parameter0.10.3
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--README.md1
-rw-r--r--src/arguments/man.rs3
-rw-r--r--src/arguments/mod.rs4
-rw-r--r--src/execute/exec_commands.rs1
-rw-r--r--src/execute/exec_inputs.rs1
-rw-r--r--src/execute/job_log.rs57
-rw-r--r--src/execute/receive.rs4
9 files changed, 50 insertions, 25 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2045924..3fdd9c0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
[root]
name = "parallel"
-version = "0.10.2"
+version = "0.10.3"
dependencies = [
"arrayvec 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index ed73b67..cdbbc7d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "parallel"
-version = "0.10.2"
+version = "0.10.3"
authors = ["Michael Aaron Murphy <mmstickman@gmail.com>"]
license = "MIT"
description = "Command-line CPU load balancer for executing jobs in parallel"
diff --git a/README.md b/README.md
index d0fc877..f7eb4ba 100644
--- a/README.md
+++ b/README.md
@@ -252,6 +252,7 @@ operates:
- **-h**, **--help**: Prints the manual for the application (recommended to pipe it to `less`).
- **-j**, **--jobs**: Defines the number of jobs/threads to run in parallel.
- **--joblog**: Logs job statistics to a designated file as they are completed.
+- **--joblog-8601**: Writes the start time in the ISO 8601 format: `YYYY-MM-DD hh:mm:ss`
- **--memfree**: Defines the minimum amount of memory available before starting the next job.
- **-n**, **--max-args**: Groups up to a certain number of arguments together in the same command line.
- **--num-cpu-cores**: Prints the number of CPU cores in the system and exits.
diff --git a/src/arguments/man.rs b/src/arguments/man.rs
index a701022..29ce30e 100644
--- a/src/arguments/man.rs
+++ b/src/arguments/man.rs
@@ -94,6 +94,9 @@ OPTIONS
--joblog:
Logs job statistics to a designated file as they are completed.
+ --joblog-8601:
+ Writes the start time in the ISO 8601 format: `YYYY-MM-DD hh:mm:ss`
+
--memfree:
Defines the minimum amount of memory available before starting the next job.
diff --git a/src/arguments/mod.rs b/src/arguments/mod.rs
index d71f511..8e6468a 100644
--- a/src/arguments/mod.rs
+++ b/src/arguments/mod.rs
@@ -34,6 +34,7 @@ pub const DRY_RUN: u16 = 64;
pub const SHELL_QUOTE: u16 = 128;
pub const ETA: u16 = 256;
pub const JOBLOG: u16 = 512;
+pub const JOBLOG_8601: u16 = 1024;
/// `Args` is a collection of critical options and arguments that were collected at
/// startup of the application.
@@ -142,6 +143,7 @@ impl Args {
index += 1;
self.flags |= JOBLOG;
},
+ "joblog-8601" => self.flags |= JOBLOG_8601,
"jobs" => {
let val = arguments.get(index).ok_or(ParseErr::JobsNoValue)?;
self.ncores = jobs::parse(val)?;
@@ -172,7 +174,7 @@ impl Args {
},
"verbose" => self.flags |= VERBOSE_MODE,
"version" => {
- println!("MIT/Rust Parallel 0.10.1\n");
+ println!("MIT/Rust Parallel 0.10.3\n");
exit(0);
},
"tmpdir" | "tempdir" => {
diff --git a/src/execute/exec_commands.rs b/src/execute/exec_commands.rs
index 8f7dfc9..20eb811 100644
--- a/src/execute/exec_commands.rs
+++ b/src/execute/exec_commands.rs
@@ -86,6 +86,7 @@ impl ExecCommands {
runtime: runtime.num_nanoseconds().unwrap_or(0) as u64,
exit_value: exit_value,
signal: signal,
+ flags: self.flags,
command: command_buffer.clone(),
}));
}
diff --git a/src/execute/exec_inputs.rs b/src/execute/exec_inputs.rs
index b688d93..53f0e09 100644
--- a/src/execute/exec_inputs.rs
+++ b/src/execute/exec_inputs.rs
@@ -66,6 +66,7 @@ impl ExecInputs {
runtime: runtime.num_nanoseconds().unwrap_or(0) as u64,
exit_value: exit_value,
signal: signal,
+ flags: flags,
command: input.clone(),
}));
}
diff --git a/src/execute/job_log.rs b/src/execute/job_log.rs
index b0d727e..98cc2d8 100644
--- a/src/execute/job_log.rs
+++ b/src/execute/job_log.rs
@@ -1,7 +1,8 @@
+use arguments::JOBLOG_8601;
use misc::NumToA;
use std::fs::File;
use std::io::{Write, BufWriter};
-use time::Timespec;
+use time::{at, Timespec};
// Each `JobLog` consists of a single job's statistics ready to be written to the job log file.
pub struct JobLog {
@@ -15,6 +16,8 @@ pub struct JobLog {
pub exit_value: i32,
/// The `signal` contains a non-zero value if the job was killed by a signal
pub signal: i32,
+ /// Contains the configuration parameters for the joblog
+ pub flags: u16,
/// The actual `command` that was executed for this job
pub command: String
}
@@ -30,29 +33,37 @@ impl JobLog {
let _ = joblog.write(b" ");
}
- // 2: StartTime in seconds, with up to two decimal places
- let bytes_written = self.start_time.sec.numtoa(10, id_buffer);
- let _ = joblog.write(&id_buffer[0..bytes_written]);
- let _ = joblog.write(b".");
- let decimal = (self.start_time.nsec % 1_000_000_000) / 1_000_000;
- if decimal == 0 {
- let _ = joblog.write(b"000");
+ // 2: StartTime
+ if self.flags & JOBLOG_8601 != 0 {
+ // ISO 8601 representation of the time
+ let tm = at(self.start_time);
+ let message = format!("{}-{:02}-{:02} {:02}:{:02}:{:02} ", 1900+tm.tm_year, 1+tm.tm_mon,
+ tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+ let _ = joblog.write(message.as_bytes());
+
} else {
- let bytes_written = decimal.numtoa(10, id_buffer);
- match bytes_written {
- 1 => { let _ = joblog.write(b"00"); },
- 2 => { let _ = joblog.write(b"0"); },
- _ => (),
- };
+ // Represented in seconds, with two decimal places
+ let bytes_written = self.start_time.sec.numtoa(10, id_buffer);
let _ = joblog.write(&id_buffer[0..bytes_written]);
- }
- for _ in 0..16-(bytes_written+4) {
- let _ = joblog.write(b" ");
+ let _ = joblog.write(b".");
+ let decimal = (self.start_time.nsec % 1_000_000_000) / 1_000_000;
+ if decimal == 0 {
+ let _ = joblog.write(b"000");
+ } else {
+ let bytes_written = decimal.numtoa(10, id_buffer);
+ match bytes_written {
+ 1 => { let _ = joblog.write(b"00"); },
+ 2 => { let _ = joblog.write(b"0"); },
+ _ => (),
+ };
+ let _ = joblog.write(&id_buffer[0..bytes_written]);
+ }
+ let _ = joblog.write(b" ");
}
// 3: Runtime in seconds, with up to three decimal places.
let bytes_written = (self.runtime / 1_000_000_000).numtoa(10, id_buffer);
- for _ in 0..10-(bytes_written + 4) {
+ for _ in 0..6-bytes_written {
let _ = joblog.write(b" ");
}
let _ = joblog.write(&id_buffer[0..bytes_written]);
@@ -92,7 +103,7 @@ impl JobLog {
}
/// Creates the column headers in the first line of the job log file
-pub fn create(file: &mut File, padding: usize) {
+pub fn create(file: &mut File, padding: usize, flags: u16) {
let mut joblog = BufWriter::new(file);
// Sequence column is at least 10 chars long, counting space separator.
@@ -100,8 +111,12 @@ pub fn create(file: &mut File, padding: usize) {
let _ = joblog.write(b"Sequence ");
for _ in 0..id_column_resize { let _ = joblog.write(b" "); }
- // StartTime column is always 17 chars long
- let _ = joblog.write(b"StartTime(s) ");
+ if flags & JOBLOG_8601 != 0 {
+ let _ = joblog.write(b"StartTime(ISO-8601) ");
+ } else {
+ let _ = joblog.write(b"StartTime(s) ");
+ }
+
// Remaining columns, with the runtim column left-padded.
let _ = joblog.write(b"Runtime(s) ExitVal Signal Command\n");
diff --git a/src/execute/receive.rs b/src/execute/receive.rs
index 1fc812e..1bdf84e 100644
--- a/src/execute/receive.rs
+++ b/src/execute/receive.rs
@@ -75,6 +75,8 @@ pub fn receive_messages(input_rx: Receiver<State>, args: Args, base: &str, proce
let stdout = io::stdout();
let stderr = io::stderr();
+ // Store the flags value outside of the `args` structure
+ let flags = args.flags;
// Keeps track of which job is currently allowed to print to standard output/error.
let mut counter = 0;
// In the event that the joblog parameter was passed, a counter will be needed for jobs.
@@ -107,7 +109,7 @@ pub fn receive_messages(input_rx: Receiver<State>, args: Args, base: &str, proce
if id_pad_length < 10 { id_pad_length = 10; }
let _ = fs::remove_file(&path);
let mut file = fs::OpenOptions::new().create(true).write(true).open(path).unwrap();
- job_log::create(&mut file, id_pad_length);
+ job_log::create(&mut file, id_pad_length, flags);
file
});