mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 04:50:36 +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/),
|
||||
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
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
use std::{
|
||||
env,
|
||||
process::{Command, Stdio},
|
||||
sync::Weak,
|
||||
};
|
||||
use std::{env, process::Stdio, sync::Weak};
|
||||
|
||||
use mlua::prelude::*;
|
||||
use os_str_bytes::RawOsString;
|
||||
use smol::{channel::Sender, unblock};
|
||||
use smol::{channel::Sender, process::Command};
|
||||
|
||||
use crate::{utils::table::TableBuilder, LuneMessage};
|
||||
|
||||
|
@ -120,24 +116,19 @@ async fn process_spawn(
|
|||
lua: &Lua,
|
||||
(program, args): (String, Option<Vec<String>>),
|
||||
) -> LuaResult<LuaTable> {
|
||||
// Create and spawn a **blocking** child process to prevent
|
||||
// issues with yielding across the metamethod/c-call boundary
|
||||
// Create and spawn our child process
|
||||
let pwd = env::current_dir()?;
|
||||
let output = unblock(move || {
|
||||
let mut cmd = Command::new(program);
|
||||
if let Some(args) = args {
|
||||
cmd.args(args);
|
||||
}
|
||||
let child = cmd
|
||||
.current_dir(pwd)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?;
|
||||
child.wait_with_output()
|
||||
})
|
||||
.await
|
||||
.map_err(LuaError::external)?;
|
||||
let mut cmd = Command::new(program);
|
||||
if let Some(args) = args {
|
||||
cmd.args(args);
|
||||
}
|
||||
let output = cmd
|
||||
.current_dir(pwd)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.output()
|
||||
.await?;
|
||||
// NOTE: If an exit code was not given by the child process,
|
||||
// we default to 1 if it yielded any error output, otherwise 0
|
||||
let code = output
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{collections::HashSet, process::ExitCode, sync::Arc};
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use anyhow::{bail, Result};
|
||||
use mlua::prelude::*;
|
||||
use smol::LocalExecutor;
|
||||
|
||||
|
@ -12,9 +12,6 @@ use crate::{
|
|||
utils::formatting::pretty_format_luau_error,
|
||||
};
|
||||
|
||||
#[cfg(not(test))]
|
||||
use crate::utils::formatting::format_label;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum LuneGlobal {
|
||||
Console,
|
||||
|
@ -43,7 +40,6 @@ pub(crate) enum LuneMessage {
|
|||
Exit(u8),
|
||||
Spawned,
|
||||
Finished,
|
||||
Error(anyhow::Error),
|
||||
LuaError(mlua::Error),
|
||||
}
|
||||
|
||||
|
@ -97,28 +93,21 @@ impl Lune {
|
|||
}
|
||||
}
|
||||
// Spawn the main thread from our entrypoint script
|
||||
let script_lua = lua.clone();
|
||||
let script_name = name.to_string();
|
||||
let script_chunk = chunk.to_string();
|
||||
sender.send(LuneMessage::Spawned).await?;
|
||||
exec.spawn(async move {
|
||||
sender.send(LuneMessage::Spawned).await?;
|
||||
let result = lua
|
||||
let result = script_lua
|
||||
.load(&script_chunk)
|
||||
.set_name(&format!("={}", script_name))
|
||||
.unwrap()
|
||||
.call_async::<_, LuaMultiValue>(LuaMultiValue::new())
|
||||
.eval_async::<LuaValue>()
|
||||
.await;
|
||||
let message = match result {
|
||||
Ok(_) => LuneMessage::Finished,
|
||||
#[cfg(test)]
|
||||
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
|
||||
match result {
|
||||
Err(e) => sender.send(LuneMessage::LuaError(e)).await,
|
||||
Ok(_) => sender.send(LuneMessage::Finished).await,
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
// Run the executor until there are no tasks left,
|
||||
|
@ -153,11 +142,6 @@ impl Lune {
|
|||
}
|
||||
LuneMessage::Spawned => task_count += 1,
|
||||
LuneMessage::Finished => task_count -= 1,
|
||||
LuneMessage::Error(e) => {
|
||||
eprintln!("{}", e);
|
||||
got_error = true;
|
||||
task_count += 1;
|
||||
}
|
||||
LuneMessage::LuaError(e) => {
|
||||
eprintln!("{}", pretty_format_luau_error(&e));
|
||||
got_error = true;
|
||||
|
@ -166,6 +150,7 @@ impl Lune {
|
|||
};
|
||||
// If there are no tasks left running, it is now
|
||||
// safe to close the receiver and end execution
|
||||
println!("{}", task_count);
|
||||
if task_count == 0 {
|
||||
receiver.close();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Debug;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::sync::Weak;
|
||||
|
||||
use mlua::prelude::*;
|
||||
|
@ -14,6 +14,16 @@ pub enum TaskRunMode {
|
|||
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>(
|
||||
lua: &Lua,
|
||||
mode: TaskRunMode,
|
||||
|
|
Loading…
Reference in a new issue