Changeset

13591:382d1a92006f

mod_admin_shell: Don't pause async thread while waiting for promise result This allows us to continue sending/receiving on the session, for example if the promise will be resolved by other data that the client is going to send. Specifically, this allows the repl-request-input to work without a deadlock. It does open the door to interleaved commands/results, which may not be a good thing overall, but can be restricted separately if necessary (e.g. a flag on the session).
author Matthew Wild <mwild1@gmail.com>
date Tue, 07 Jan 2025 18:15:50 +0000
parents 13590:d66f30855822
children 13592:34da8cc10b82
files plugins/mod_admin_shell.lua
diffstat 1 files changed, 23 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_admin_shell.lua	Tue Jan 07 18:10:59 2025 +0000
+++ b/plugins/mod_admin_shell.lua	Tue Jan 07 18:15:50 2025 +0000
@@ -266,25 +266,33 @@
 		end
 	end
 
+	local function send_result(taskok, message)
+		if not message then
+			if type(taskok) ~= "string" and useglobalenv then
+				taskok = session.serialize(taskok);
+			end
+			result:text("Result: "..tostring(taskok));
+		elseif (not taskok) and message then
+			result.attr.type = "error";
+			result:text("Error: "..tostring(message));
+		else
+			result:text("OK: "..tostring(message));
+		end
+
+		event.origin.send(result);
+	end
+
 	local taskok, message = chunk();
 
 	if promise.is_promise(taskok) then
-		taskok, message = async.wait_for(taskok);
+		taskok:next(function (resolved_message)
+			send_result(true, resolved_message);
+		end, function (rejected_message)
+			send_result(nil, rejected_message);
+		end);
+	else
+		send_result(taskok, message);
 	end
-
-	if not message then
-		if type(taskok) ~= "string" and useglobalenv then
-			taskok = session.serialize(taskok);
-		end
-		result:text("Result: "..tostring(taskok));
-	elseif (not taskok) and message then
-		result.attr.type = "error";
-		result:text("Error: "..tostring(message));
-	else
-		result:text("OK: "..tostring(message));
-	end
-
-	event.origin.send(result);
 end
 
 module:hook("admin/repl-input", function (event)