aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2025-01-07 18:15:50 +0000
committerMatthew Wild <mwild1@gmail.com>2025-01-07 18:15:50 +0000
commit957c69461fc3d13ef945cb0ccd62b601f18f2e9a (patch)
tree8b64a3792168c69267f32aac14a911277f2b9a11
parent91776f57efa0fa62db8ace714b0997dca3ea823c (diff)
downloadprosody-957c69461fc3d13ef945cb0ccd62b601f18f2e9a.tar.gz
prosody-957c69461fc3d13ef945cb0ccd62b601f18f2e9a.zip
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).
-rw-r--r--plugins/mod_admin_shell.lua36
1 files changed, 22 insertions, 14 deletions
diff --git a/plugins/mod_admin_shell.lua b/plugins/mod_admin_shell.lua
index c32048c3..131bd070 100644
--- a/plugins/mod_admin_shell.lua
+++ b/plugins/mod_admin_shell.lua
@@ -266,25 +266,33 @@ local function handle_line(event)
end
end
- local taskok, message = chunk();
+ 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
- if promise.is_promise(taskok) then
- taskok, message = async.wait_for(taskok);
+ event.origin.send(result);
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));
+ local taskok, message = chunk();
+
+ if promise.is_promise(taskok) then
+ taskok:next(function (resolved_message)
+ send_result(true, resolved_message);
+ end, function (rejected_message)
+ send_result(nil, rejected_message);
+ end);
else
- result:text("OK: "..tostring(message));
+ send_result(taskok, message);
end
-
- event.origin.send(result);
end
module:hook("admin/repl-input", function (event)