Software /
code /
prosody
Comparison
plugins/mod_admin_shell.lua @ 13334:aefcb6b4f47d
mod_admin_shell: Add debug:async() command to show blocked async runners
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 21 Nov 2023 18:48:58 +0000 |
parent | 13287:1e2d65403867 |
child | 13338:470ab6b55e93 |
comparison
equal
deleted
inserted
replaced
13333:fa4143163e01 | 13334:aefcb6b4f47d |
---|---|
319 elseif section == "stats" then -- luacheck: ignore 542 | 319 elseif section == "stats" then -- luacheck: ignore 542 |
320 print [[stats:show(pattern) - Show internal statistics, optionally filtering by name with a pattern]] | 320 print [[stats:show(pattern) - Show internal statistics, optionally filtering by name with a pattern]] |
321 print [[stats:show():cfgraph() - Show a cumulative frequency graph]] | 321 print [[stats:show():cfgraph() - Show a cumulative frequency graph]] |
322 print [[stats:show():histogram() - Show a histogram of selected metric]] | 322 print [[stats:show():histogram() - Show a histogram of selected metric]] |
323 elseif section == "debug" then | 323 elseif section == "debug" then |
324 print [[debug:async() - Show information about pending asynchronous tasks]] | |
324 print [[debug:logevents(host) - Enable logging of fired events on host]] | 325 print [[debug:logevents(host) - Enable logging of fired events on host]] |
325 print [[debug:events(host, event) - Show registered event handlers]] | 326 print [[debug:events(host, event) - Show registered event handlers]] |
326 print [[debug:timers() - Show information about scheduled timers]] | 327 print [[debug:timers() - Show information about scheduled timers]] |
327 elseif section == "watch" then | 328 elseif section == "watch" then |
328 print [[watch:log() - Follow debug logs]] | 329 print [[watch:log() - Follow debug logs]] |
2012 end | 2013 end |
2013 end | 2014 end |
2014 return true; | 2015 return true; |
2015 end | 2016 end |
2016 | 2017 |
2018 function def_env.debug:async(runner_id) | |
2019 local print = self.session.print; | |
2020 local async = require "prosody.util.async"; | |
2021 local time_now = require "prosody.util.time".now(); | |
2022 | |
2023 local function format_time(t) | |
2024 return os.date("%F %T", math.floor(normalize_time(t))); | |
2025 end | |
2026 | |
2027 if runner_id then | |
2028 local matched; | |
2029 for runner, since in pairs(async.waiting_runners) do | |
2030 if runner.id == runner_id then | |
2031 matched = runner; | |
2032 print("ID ", runner.id); | |
2033 local f = runner.func; | |
2034 if f == async.default_runner_func then | |
2035 print("Function ", tostring(runner.current_item).." (from work queue)"); | |
2036 else | |
2037 print("Function ", tostring(f)); | |
2038 if st.is_stanza(runner.current_item) then | |
2039 print("Stanza:") | |
2040 print("\t"..runner.current_item:indent(2):pretty_print()); | |
2041 else | |
2042 print("Work item", serialize(runner.current_item, "debug")); | |
2043 end | |
2044 end | |
2045 | |
2046 print("Coroutine ", tostring(runner.thread).." ("..coroutine.status(runner.thread)..")"); | |
2047 print("Since ", since); | |
2048 print("Status ", ("%s since %s (%0.2f seconds ago)"):format(runner.state, os.date("%Y-%m-%d %R:%S", math.floor(since)), time_now-since)); | |
2049 print(""); | |
2050 print(debug.traceback(runner.thread)); | |
2051 return true, "Runner is "..runner.state; | |
2052 end | |
2053 end | |
2054 return nil, "Runner not found or is currently idle"; | |
2055 end | |
2056 | |
2057 local row = format_table({ { title = "ID", width = 12 }, { title = "Function", width = "10p" }, { title = "Status", width = "16" }, { title = "Location", width = "10p" } }, self.session.width); | |
2058 print(row()) | |
2059 | |
2060 local c = 0; | |
2061 for runner, since in pairs(async.waiting_runners) do | |
2062 c = c + 1; | |
2063 local f = runner.func; | |
2064 if f == async.default_runner_func then | |
2065 f = runner.current_item; | |
2066 end | |
2067 -- We want to fetch the location in the code that the runner yielded from, | |
2068 -- excluding util.async's wrapper code. A level of `2` assumes that we | |
2069 -- yielded directly from a function in util.async. This is *currently* true | |
2070 -- of all util.async yields, but it's fragile. | |
2071 local location = debug.getinfo(runner.thread, 2); | |
2072 print(row { | |
2073 runner.id; | |
2074 tostring(f); | |
2075 ("%s (%0.2fs)"):format(runner.state, time_now - since); | |
2076 location.short_src..(location.currentline and ":"..location.currentline or ""); | |
2077 }); | |
2078 end | |
2079 return true, ("%d runners pending"):format(c); | |
2080 end | |
2081 | |
2017 -- COMPAT: debug:timers() was timer:info() for some time in trunk | 2082 -- COMPAT: debug:timers() was timer:info() for some time in trunk |
2018 def_env.timer = { info = def_env.debug.timers }; | 2083 def_env.timer = { info = def_env.debug.timers }; |
2019 | 2084 |
2020 def_env.stats = {}; | 2085 def_env.stats = {}; |
2021 | 2086 |