diff options
| author | ruki <[email protected]> | 2020-02-05 23:03:41 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-02-07 22:45:56 +0800 |
| commit | 97d20dc309b8064ab7bafc69a6784caa4df9b107 (patch) | |
| tree | 5925aeb2176d719fb4b8b7fa68214649347955af | |
| parent | 1cac0feefb18328d14deff5b1fddb95fc7175353 (diff) | |
improve runjobs tips
| -rw-r--r-- | xmake/actions/update/main.lua | 14 | ||||
| -rw-r--r-- | xmake/core/base/scheduler.lua | 19 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/scheduler.lua | 6 | ||||
| -rw-r--r-- | xmake/modules/private/async/runjobs.lua | 78 |
4 files changed, 105 insertions, 12 deletions
diff --git a/xmake/actions/update/main.lua b/xmake/actions/update/main.lua index a0aa4bd4a..33e726e17 100644 --- a/xmake/actions/update/main.lua +++ b/xmake/actions/update/main.lua @@ -145,7 +145,8 @@ function _install(sourcedir) local installdir = is_host("windows") and os.programdir() or "~/.local/bin" -- trace - cprintf("\r${yellow} => ${clear}installing to %s .. ", installdir) + utils.clearline() + cprintf("${yellow} => ${clear}installing to %s .. ", installdir) local ok = try { function () @@ -185,7 +186,8 @@ function _install(sourcedir) -- trace if ok then - cprint("\r${yellow} => ${clear}install to %s .. ${green}ok ", installdir) + utils.clearline() + cprint("${yellow} => ${clear}install to %s .. ${color.success}${text.success}", installdir) else raise("install failed!") end @@ -341,7 +343,8 @@ function main() local download_task = function () for idx, url in ipairs(mainurls) do - cprintf("\r${yellow} => ${clear}downloading %s .. ", url) + utils.clearline() + cprintf("${yellow} => ${clear}downloading %s .. ", url) local ok = try { function () @@ -361,11 +364,12 @@ function main() end } } + utils.clearline() if ok then - cprint("\r${yellow} => ${clear}download %s .. ${color.success}${text.success} ", url) + cprint("${yellow} => ${clear}download %s .. ${color.success}${text.success}", url) break else - cprint("\r${yellow} => ${clear}download %s .. ${color.failure}${text.failure} ", url) + cprint("${yellow} => ${clear}download %s .. ${color.failure}${text.failure}", url) end if not ok and idx == #mainurls then raise("download failed!") diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua index b1091caf6..5e68be8c2 100644 --- a/xmake/core/base/scheduler.lua +++ b/xmake/core/base/scheduler.lua @@ -52,6 +52,16 @@ function _coroutine:name_set(name) self._NAME = name end +-- get the waiting poller object +function _coroutine:waitobj() + return self._WAITOBJ +end + +-- set the waiting poller object +function _coroutine:waitobj_set(obj) + self._WAITOBJ = obj +end + -- get the raw coroutine thread function _coroutine:thread() return self._THREAD @@ -146,6 +156,7 @@ function scheduler:_poller_resume_co(co, events) assert(co:is_suspended()) -- resume this coroutine task + co:waitobj_set(nil) self:_co_tasks_suspended():remove(co) return self:co_resume(co, (bit.band(events, poller.EV_POLLER_ERROR) ~= 0) and -1 or events) end @@ -550,6 +561,7 @@ function scheduler:poller_wait(obj, events, timeout) if timeout > 0 then timer_task = self:_timer():post(function (cancel) if not cancel and running:is_suspended() then + running:waitobj_set(nil) self:_co_tasks_suspended():remove(running) self:co_resume(running, 0) end @@ -572,6 +584,9 @@ function scheduler:poller_wait(obj, events, timeout) -- save the suspended coroutine self:_co_tasks_suspended():insert(running) + -- save the waiting poller object + running:waitobj_set(obj) + -- wait return self:co_suspend() end @@ -621,6 +636,7 @@ function scheduler:poller_waitproc(obj, timeout) timer_task = self:_timer():post(function (cancel) if not cancel and running:is_suspended() then pollerdata.co_waiting = nil + running:waitobj_set(nil) self:_co_tasks_suspended():remove(running) self:co_resume(running, 0) end @@ -636,6 +652,9 @@ function scheduler:poller_waitproc(obj, timeout) -- save the suspended coroutine self:_co_tasks_suspended():insert(running) + -- save the waiting poller object + running:waitobj_set(obj) + -- wait local ok = self:co_suspend() return ok, pollerdata.proc_status diff --git a/xmake/core/sandbox/modules/import/core/base/scheduler.lua b/xmake/core/sandbox/modules/import/core/base/scheduler.lua index c899fcd34..254f78591 100644 --- a/xmake/core/sandbox/modules/import/core/base/scheduler.lua +++ b/xmake/core/sandbox/modules/import/core/base/scheduler.lua @@ -22,9 +22,15 @@ local sandbox_core_base_scheduler = sandbox_core_base_scheduler or {} -- load modules +local poller = require("base/poller") local scheduler = require("base/scheduler") local raise = require("sandbox/modules/raise") +-- the poller object type +sandbox_core_base_scheduler.OT_SOCK = poller.OT_SOCK +sandbox_core_base_scheduler.OT_PIPE = poller.OT_PIPE +sandbox_core_base_scheduler.OT_PROC = poller.OT_PROC + -- start a new coroutine task function sandbox_core_base_scheduler.co_start(cotask, ...) local co, errors = scheduler:co_start(cotask, ...) diff --git a/xmake/modules/private/async/runjobs.lua b/xmake/modules/private/async/runjobs.lua index 1c12bf63c..fcca3e65d 100644 --- a/xmake/modules/private/async/runjobs.lua +++ b/xmake/modules/private/async/runjobs.lua @@ -20,6 +20,40 @@ -- imports import("core.base.scheduler") +import("core.base.hashset") + +-- get waiting objects +function _get_waiting_objects(group_name) + local objs = hashset.new() + for _, co in ipairs(scheduler.co_group(group_name)) do + if not co:is_dead() then + local obj = co:waitobj() + if obj then + objs:insert(obj) + end + end + end + return objs +end + +-- print back characters +function _print_backchars(backnum) + if backnum > 0 then + local str = "" + for i = 1, backnum do + str = str .. '\b' + end + for i = 1, backnum do + str = str .. ' ' + end + for i = 1, backnum do + str = str .. '\b' + end + if #str > 0 then + printf(str) + end + end +end -- asynchronous run jobs function main(name, jobfunc, opt) @@ -29,16 +63,14 @@ function main(name, jobfunc, opt) local total = opt.total or 1 local comax = opt.comax or total local timeout = opt.timeout or 500 + local group_name = name assert(timeout < 60000, "runjobs: invalid timeout!") -- show waiting tips? local waitindex = 0 local waitchars = opt.waitchars or {'\\', '-', '/', '|'} + local backnum = 0 local showtips = io.isatty() and opt.showtips -- we need hide wait characters if is not a tty - if showtips then - printf(waitchars[waitindex + 1]) - io.flush() - end -- run timer local stop = false @@ -57,8 +89,41 @@ function main(name, jobfunc, opt) while not stop do os.sleep(timeout) if not stop then + + -- print back characters + _print_backchars(backnum) + + -- show waitchars waitindex = ((waitindex + 1) % #waitchars) - printf("\b" .. waitchars[waitindex + 1]) + local tips = nil + local waitobjs = _get_waiting_objects(group_name) + if waitobjs:size() > 0 then + local names = {} + for _, obj in waitobjs:keys() do + if obj:otype() == scheduler.OT_PROC then + table.insert(names, obj:name()) + elseif obj:otype() == scheduler.OT_SOCK then + table.insert(names, "sock") + elseif obj:otype() == scheduler.OT_PIPE then + table.insert(names, "pipe") + end + end + names = table.unique(names) + if #names > 0 then + names = table.concat(names, ",") + if #names > 16 then + names = names:sub(1, 16) .. ".." + end + tips = string.format("(%d/%s)", waitobjs:size(), names) + end + end + if tips then + cprintf("${dim}%s${clear} %s", tips, waitchars[waitindex + 1]) + backnum = #tips + 2 + else + printf(waitchars[waitindex + 1]) + backnum = 1 + end io.flush() end end @@ -67,7 +132,6 @@ function main(name, jobfunc, opt) -- run jobs local index = 0 - local group_name = name while index < total do running_jobs_indices = {} scheduler.co_group_begin(group_name, function () @@ -86,7 +150,7 @@ function main(name, jobfunc, opt) -- remove wait charactor if showtips then - printf("\b") + _print_backchars(backnum) io.flush() end end |
