(cli): Add event handler for left/right arrows

This commit is contained in:
Ken Hibino
2022-05-18 06:52:13 -07:00
parent b78ed063ff
commit 2c43ee9e20
2 changed files with 89 additions and 9 deletions

View File

@@ -32,6 +32,7 @@ type State struct {
err error err error
rowIdx int // highlighted row rowIdx int // highlighted row
taskState asynq.TaskState // highlighted task state in queue details view
selectedQueue *asynq.QueueInfo // queue shown on queue details view selectedQueue *asynq.QueueInfo // queue shown on queue details view
@@ -140,6 +141,7 @@ func Run(opts Options) {
if state.view == viewTypeQueues && state.rowIdx != 0 { if state.view == viewTypeQueues && state.rowIdx != 0 {
state.selectedQueue = state.queues[state.rowIdx-1] state.selectedQueue = state.queues[state.rowIdx-1]
state.view = viewTypeQueueDetails state.view = viewTypeQueueDetails
state.taskState = asynq.TaskStateActive
drawDash(s, baseStyle, &state, opts) drawDash(s, baseStyle, &state, opts)
} }
} else if ev.Rune() == '?' { } else if ev.Rune() == '?' {
@@ -164,6 +166,12 @@ func Run(opts Options) {
ticker.Reset(interval) ticker.Reset(interval)
state.view = viewTypeRedis state.view = viewTypeRedis
drawDash(s, baseStyle, &state, opts) drawDash(s, baseStyle, &state, opts)
} else if (ev.Key() == tcell.KeyRight || ev.Rune() == 'l') && state.view == viewTypeQueueDetails {
state.taskState = nextTaskState(state.taskState)
drawDash(s, baseStyle, &state, opts)
} else if (ev.Key() == tcell.KeyLeft || ev.Rune() == 'h') && state.view == viewTypeQueueDetails {
state.taskState = prevTaskState(state.taskState)
drawDash(s, baseStyle, &state, opts)
} }
} }

View File

@@ -22,37 +22,40 @@ func drawDash(s tcell.Screen, style tcell.Style, state *State, opts Options) {
switch state.view { switch state.view {
case viewTypeQueues: case viewTypeQueues:
d.Println("=== Queues ===", style.Bold(true)) d.Println("=== Queues ===", style.Bold(true))
d.NL() // empty line d.NL()
drawQueueSizeGraphs(d, style, state) drawQueueSizeGraphs(d, style, state)
d.NL() // empty line d.NL()
drawQueueTable(d, style, state) drawQueueTable(d, style, state)
case viewTypeQueueDetails: case viewTypeQueueDetails:
d.Println(fmt.Sprintf("=== Queues > %s ===", state.selectedQueue.Queue), style) d.Println(fmt.Sprintf("=== Queues > %s ===", state.selectedQueue.Queue), style.Bold(true))
d.NL() d.NL()
drawQueueInfoBanner(d, style, state) drawQueueInfoBanner(d, style, state)
d.NL()
d.Println("+++ Tasks +++", style.Bold(true))
drawTaskStateBreakdown(d, style, state)
case viewTypeServers: case viewTypeServers:
d.Println("=== Servers ===", style.Bold(true)) d.Println("=== Servers ===", style.Bold(true))
d.NL() // empty line d.NL()
// TODO: Draw body // TODO: Draw body
case viewTypeSchedulers: case viewTypeSchedulers:
d.Println("=== Schedulers === ", style.Bold(true)) d.Println("=== Schedulers === ", style.Bold(true))
d.NL() // empty line d.NL()
// TODO: Draw body // TODO: Draw body
case viewTypeRedis: case viewTypeRedis:
d.Println("=== Redis Info === ", style.Bold(true)) d.Println("=== Redis Info === ", style.Bold(true))
d.NL() // empty line d.NL()
d.Println(fmt.Sprintf("Version: %s", state.redisInfo.version), style) d.Println(fmt.Sprintf("Version: %s", state.redisInfo.version), style)
d.Println(fmt.Sprintf("Uptime: %s", state.redisInfo.uptime), style) d.Println(fmt.Sprintf("Uptime: %s", state.redisInfo.uptime), style)
d.Println(fmt.Sprintf("Memory Usage: %s", ByteCount(int64(state.redisInfo.memoryUsage))), style) d.Println(fmt.Sprintf("Memory Usage: %s", ByteCount(int64(state.redisInfo.memoryUsage))), style)
d.Println(fmt.Sprintf("Peak Memory Usage: %s", ByteCount(int64(state.redisInfo.peakMemoryUsage))), style) d.Println(fmt.Sprintf("Peak Memory Usage: %s", ByteCount(int64(state.redisInfo.peakMemoryUsage))), style)
case viewTypeHelp: case viewTypeHelp:
d.Println("=== HELP ===", style.Bold(true)) d.Println("=== HELP ===", style.Bold(true))
d.NL() // empty line d.NL()
// TODO: Draw HELP body // TODO: Draw HELP body
} }
if opts.DebugMode { if opts.DebugMode {
d.Println(fmt.Sprintf("DEBUG: rowIdx = %d", state.rowIdx), style) d.Println(fmt.Sprintf("DEBUG: rowIdx = %d", state.rowIdx), style)
d.Println(fmt.Sprintf("DEBUG: selectedQueue = %s", state.selectedQueue), style) d.Println(fmt.Sprintf("DEBUG: selectedQueue = %s", state.selectedQueue.Queue), style)
d.Println(fmt.Sprintf("DEBUG: view = %v", state.view), style) d.Println(fmt.Sprintf("DEBUG: view = %v", state.view), style)
} }
d.GoToBottom() d.GoToBottom()
@@ -226,3 +229,72 @@ func drawQueueTable(d *ScreenDrawer, style tcell.Style, state *State) {
func drawQueueInfoBanner(d *ScreenDrawer, style tcell.Style, state *State) { func drawQueueInfoBanner(d *ScreenDrawer, style tcell.Style, state *State) {
drawTable(d, style, queueColumnConfigs, []*asynq.QueueInfo{state.selectedQueue}, -1 /* no highlited row */) drawTable(d, style, queueColumnConfigs, []*asynq.QueueInfo{state.selectedQueue}, -1 /* no highlited row */)
} }
// Define the order of states to show
var taskStates = []asynq.TaskState{
asynq.TaskStateActive,
asynq.TaskStatePending,
asynq.TaskStateAggregating,
asynq.TaskStateScheduled,
asynq.TaskStateRetry,
asynq.TaskStateArchived,
asynq.TaskStateCompleted,
}
func nextTaskState(current asynq.TaskState) asynq.TaskState {
for i, ts := range taskStates {
if current == ts {
if i == len(taskStates)-1 {
return taskStates[0]
} else {
return taskStates[i+1]
}
}
}
panic("unkown task state")
}
func prevTaskState(current asynq.TaskState) asynq.TaskState {
for i, ts := range taskStates {
if current == ts {
if i == 0 {
return taskStates[len(taskStates)-1]
} else {
return taskStates[i-1]
}
}
}
panic("unkown task state")
}
func getTaskCount(queue *asynq.QueueInfo, taskState asynq.TaskState) int {
switch taskState {
case asynq.TaskStateActive:
return queue.Active
case asynq.TaskStatePending:
return queue.Pending
case asynq.TaskStateAggregating:
return queue.Aggregating
case asynq.TaskStateScheduled:
return queue.Scheduled
case asynq.TaskStateRetry:
return queue.Retry
case asynq.TaskStateArchived:
return queue.Archived
case asynq.TaskStateCompleted:
return queue.Completed
}
panic("unkonwn task state")
}
func drawTaskStateBreakdown(d *ScreenDrawer, style tcell.Style, state *State) {
const pad = " " // padding between states
for _, ts := range taskStates {
s := style
if state.taskState == ts {
s = s.Background(tcell.ColorDarkOliveGreen)
}
d.Print(fmt.Sprintf("%s:%d", ts.String(), getTaskCount(state.selectedQueue, ts)), s)
d.Print(pad, style)
}
}