Fix queueing behaviour (#734)

This commit is contained in:
Félix Saparelli 2023-12-20 00:22:59 +13:00 committed by GitHub
parent b4a64a096a
commit eb4f2ce201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 26 deletions

10
bin/dates.mjs Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env node
const id = Math.floor(Math.random() * 100);
let n = 0;
const m = 5;
while (n < m) {
n += 1;
console.log(`[${id} : ${n}/${m}] ${new Date}`);
await new Promise(done => setTimeout(done, 2000));
}

View File

@ -8,7 +8,7 @@ use std::{
path::Path,
process::Stdio,
sync::{
atomic::{AtomicU8, Ordering},
atomic::{AtomicBool, AtomicU8, Ordering},
Arc,
},
time::Duration,
@ -199,12 +199,14 @@ pub fn make_config(args: &Args, state: &State) -> Result<Config> {
.collect(),
);
let queued = Arc::new(AtomicBool::new(false));
let quit_again = Arc::new(AtomicU8::new(0));
config.on_action_async(move |mut action| {
let add_envs = add_envs.clone();
let command = command.clone();
let emit_file = emit_file.clone();
let queued = queued.clone();
let quit_again = quit_again.clone();
let signal_map = signal_map.clone();
let workdir = workdir.clone();
@ -215,6 +217,7 @@ pub fn make_config(args: &Args, state: &State) -> Result<Config> {
let add_envs = add_envs.clone();
let command = command.clone();
let emit_file = emit_file.clone();
let queued = queued.clone();
let quit_again = quit_again.clone();
let signal_map = signal_map.clone();
let workdir = workdir.clone();
@ -409,17 +412,32 @@ pub fn make_config(args: &Args, state: &State) -> Result<Config> {
}
OnBusyUpdate::Queue => {
let job = job.clone();
tokio::spawn(async move {
job.to_wait().await;
job.start();
job.run(move |context| {
setup_process(
innerjob.clone(),
context.command.clone(),
outflags,
)
let already_queued =
queued.fetch_or(true, Ordering::SeqCst);
if already_queued {
debug!("next start is already queued, do nothing");
} else {
debug!("queueing next start of job");
tokio::spawn({
let queued = queued.clone();
async move {
trace!("waiting for job to finish");
job.to_wait().await;
trace!("job finished, starting queued");
job.start();
job.run(move |context| {
setup_process(
innerjob.clone(),
context.command.clone(),
outflags,
)
})
.await;
trace!("resetting queued state");
queued.store(false, Ordering::SeqCst);
}
});
});
}
}
}
} else {

View File

@ -2,6 +2,9 @@
## Next (YYYY-MM-DD)
- Fix Start executing even when the job is running.
- Add kill-on-drop to guarantee no two processes run at the same time.
## v1.0.2 (2023-12-09)
- Add `trace`-level logging to Job task.

View File

@ -86,9 +86,9 @@ impl CommandState {
#[cfg(not(test))]
let child = if command.options.grouped {
ErasedChild::Grouped(spawnable.group().spawn()?)
ErasedChild::Grouped(spawnable.group().kill_on_drop(true).spawn()?)
} else {
ErasedChild::Ungrouped(spawnable.spawn()?)
ErasedChild::Ungrouped(spawnable.kill_on_drop(true).spawn()?)
};
*self = Self::Running {

View File

@ -136,19 +136,23 @@ pub fn start_job(command: Arc<Command>) -> (Job, JoinHandle<()>) {
match control {
Control::Start => {
let mut spawnable = command.to_spawnable();
previous_run = Some(command_state.reset());
spawn_hook
.call(
&mut spawnable,
&JobTaskContext {
command: command.clone(),
current: &command_state,
previous: previous_run.as_ref(),
},
)
.await;
try_with_handler!(command_state.spawn(command.clone(), spawnable).await);
if command_state.is_running() {
trace!("child is running, skip");
} else {
let mut spawnable = command.to_spawnable();
previous_run = Some(command_state.reset());
spawn_hook
.call(
&mut spawnable,
&JobTaskContext {
command: command.clone(),
current: &command_state,
previous: previous_run.as_ref(),
},
)
.await;
try_with_handler!(command_state.spawn(command.clone(), spawnable).await);
}
}
Control::Stop => {
if let CommandState::Running { child, started, .. } = &mut command_state {