From 915dbf7bd9ec13a749794e30ca6f875a86add76a Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Tue, 24 Jan 2023 20:30:47 -0500 Subject: [PATCH] Fix scripts that terminate instantly hanging forever --- CHANGELOG.md | 6 ++++++ src/lib/globals/process.rs | 37 ++++++++++++++----------------------- src/lib/lib.rs | 35 ++++++++++------------------------- src/lib/utils/task.rs | 12 +++++++++++- 4 files changed, 41 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 306a991..2a0f22f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/lib/globals/process.rs b/src/lib/globals/process.rs index 7a2c274..c9520e8 100644 --- a/src/lib/globals/process.rs +++ b/src/lib/globals/process.rs @@ -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>), ) -> LuaResult { - // 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 diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 76b1abd..6e364ad 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -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::() .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(); } diff --git a/src/lib/utils/task.rs b/src/lib/utils/task.rs index d2dff48..1da30df 100644 --- a/src/lib/utils/task.rs +++ b/src/lib/utils/task.rs @@ -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( lua: &Lua, mode: TaskRunMode,