diff options
author | Matthew Wild <mwild1@gmail.com> | 2025-01-07 18:15:50 +0000 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2025-01-07 18:15:50 +0000 |
commit | 957c69461fc3d13ef945cb0ccd62b601f18f2e9a (patch) | |
tree | 8b64a3792168c69267f32aac14a911277f2b9a11 | |
parent | 91776f57efa0fa62db8ace714b0997dca3ea823c (diff) | |
download | prosody-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.lua | 36 |
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) |