mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Fix scripts that terminate instantly hanging forever
This commit is contained in:
parent
530d01fc9d
commit
915dbf7bd9
4 changed files with 41 additions and 49 deletions
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed scripts that terminate instantly sometimes hanging
|
||||||
|
|
||||||
## `0.1.1` - January 24th, 2023
|
## `0.1.1` - January 24th, 2023
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use std::{
|
use std::{env, process::Stdio, sync::Weak};
|
||||||
env,
|
|
||||||
process::{Command, Stdio},
|
|
||||||
sync::Weak,
|
|
||||||
};
|
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use smol::{channel::Sender, unblock};
|
use smol::{channel::Sender, process::Command};
|
||||||
|
|
||||||
use crate::{utils::table::TableBuilder, LuneMessage};
|
use crate::{utils::table::TableBuilder, LuneMessage};
|
||||||
|
|
||||||
|
@ -120,24 +116,19 @@ async fn process_spawn(
|
||||||
lua: &Lua,
|
lua: &Lua,
|
||||||
(program, args): (String, Option<Vec<String>>),
|
(program, args): (String, Option<Vec<String>>),
|
||||||
) -> LuaResult<LuaTable> {
|
) -> LuaResult<LuaTable> {
|
||||||
// Create and spawn a **blocking** child process to prevent
|
// Create and spawn our child process
|
||||||
// issues with yielding across the metamethod/c-call boundary
|
|
||||||
let pwd = env::current_dir()?;
|
let pwd = env::current_dir()?;
|
||||||
let output = unblock(move || {
|
let mut cmd = Command::new(program);
|
||||||
let mut cmd = Command::new(program);
|
if let Some(args) = args {
|
||||||
if let Some(args) = args {
|
cmd.args(args);
|
||||||
cmd.args(args);
|
}
|
||||||
}
|
let output = cmd
|
||||||
let child = cmd
|
.current_dir(pwd)
|
||||||
.current_dir(pwd)
|
.stdin(Stdio::null())
|
||||||
.stdin(Stdio::null())
|
.stdout(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.output()
|
||||||
.spawn()?;
|
.await?;
|
||||||
child.wait_with_output()
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.map_err(LuaError::external)?;
|
|
||||||
// NOTE: If an exit code was not given by the child process,
|
// NOTE: If an exit code was not given by the child process,
|
||||||
// we default to 1 if it yielded any error output, otherwise 0
|
// we default to 1 if it yielded any error output, otherwise 0
|
||||||
let code = output
|
let code = output
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashSet, process::ExitCode, sync::Arc};
|
use std::{collections::HashSet, process::ExitCode, sync::Arc};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use smol::LocalExecutor;
|
use smol::LocalExecutor;
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@ use crate::{
|
||||||
utils::formatting::pretty_format_luau_error,
|
utils::formatting::pretty_format_luau_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
use crate::utils::formatting::format_label;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum LuneGlobal {
|
pub enum LuneGlobal {
|
||||||
Console,
|
Console,
|
||||||
|
@ -43,7 +40,6 @@ pub(crate) enum LuneMessage {
|
||||||
Exit(u8),
|
Exit(u8),
|
||||||
Spawned,
|
Spawned,
|
||||||
Finished,
|
Finished,
|
||||||
Error(anyhow::Error),
|
|
||||||
LuaError(mlua::Error),
|
LuaError(mlua::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,28 +93,21 @@ impl Lune {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Spawn the main thread from our entrypoint script
|
// Spawn the main thread from our entrypoint script
|
||||||
|
let script_lua = lua.clone();
|
||||||
let script_name = name.to_string();
|
let script_name = name.to_string();
|
||||||
let script_chunk = chunk.to_string();
|
let script_chunk = chunk.to_string();
|
||||||
|
sender.send(LuneMessage::Spawned).await?;
|
||||||
exec.spawn(async move {
|
exec.spawn(async move {
|
||||||
sender.send(LuneMessage::Spawned).await?;
|
let result = script_lua
|
||||||
let result = lua
|
|
||||||
.load(&script_chunk)
|
.load(&script_chunk)
|
||||||
.set_name(&format!("={}", script_name))
|
.set_name(&format!("={}", script_name))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.call_async::<_, LuaMultiValue>(LuaMultiValue::new())
|
.eval_async::<LuaValue>()
|
||||||
.await;
|
.await;
|
||||||
let message = match result {
|
match result {
|
||||||
Ok(_) => LuneMessage::Finished,
|
Err(e) => sender.send(LuneMessage::LuaError(e)).await,
|
||||||
#[cfg(test)]
|
Ok(_) => sender.send(LuneMessage::Finished).await,
|
||||||
Err(e) => LuneMessage::Error(anyhow!("{}", pretty_format_luau_error(&e))),
|
}
|
||||||
#[cfg(not(test))]
|
|
||||||
Err(e) => LuneMessage::Error(anyhow!(
|
|
||||||
"\n{}\n{}",
|
|
||||||
format_label("ERROR"),
|
|
||||||
pretty_format_luau_error(&e)
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
sender.send(message).await
|
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
// Run the executor until there are no tasks left,
|
// Run the executor until there are no tasks left,
|
||||||
|
@ -153,11 +142,6 @@ impl Lune {
|
||||||
}
|
}
|
||||||
LuneMessage::Spawned => task_count += 1,
|
LuneMessage::Spawned => task_count += 1,
|
||||||
LuneMessage::Finished => task_count -= 1,
|
LuneMessage::Finished => task_count -= 1,
|
||||||
LuneMessage::Error(e) => {
|
|
||||||
eprintln!("{}", e);
|
|
||||||
got_error = true;
|
|
||||||
task_count += 1;
|
|
||||||
}
|
|
||||||
LuneMessage::LuaError(e) => {
|
LuneMessage::LuaError(e) => {
|
||||||
eprintln!("{}", pretty_format_luau_error(&e));
|
eprintln!("{}", pretty_format_luau_error(&e));
|
||||||
got_error = true;
|
got_error = true;
|
||||||
|
@ -166,6 +150,7 @@ impl Lune {
|
||||||
};
|
};
|
||||||
// If there are no tasks left running, it is now
|
// If there are no tasks left running, it is now
|
||||||
// safe to close the receiver and end execution
|
// safe to close the receiver and end execution
|
||||||
|
println!("{}", task_count);
|
||||||
if task_count == 0 {
|
if task_count == 0 {
|
||||||
receiver.close();
|
receiver.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::{self, Debug};
|
||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
@ -14,6 +14,16 @@ pub enum TaskRunMode {
|
||||||
Deferred,
|
Deferred,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for TaskRunMode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Blocking => write!(f, "Blocking"),
|
||||||
|
Self::Instant => write!(f, "Instant"),
|
||||||
|
Self::Deferred => write!(f, "Deferred"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run_registered_task<T>(
|
pub async fn run_registered_task<T>(
|
||||||
lua: &Lua,
|
lua: &Lua,
|
||||||
mode: TaskRunMode,
|
mode: TaskRunMode,
|
||||||
|
|
Loading…
Reference in a new issue