Commit 184b2d23 authored by Stefan Raspl's avatar Stefan Raspl Committed by Paolo Bonzini

tools/kvm_stat: reduce perceived idle time on filter updates

Whenever a user adds a filter, we
* redraw the header immediately for a snappy response
* print a message indicating to the user that we're busy while the
  noticeable delay induced by updating all of the stats objects takes place
* update the statistics ASAP (i.e. after 0.25s instead of 3s) to be
  consistent with behavior on startup
To do so, we split the Tui's refresh() method to allow for drawing header
and stats separately, and trigger a header refresh whenever we are about
to do something that takes a while - like updating filters.
Signed-off-by: default avatarStefan Raspl <raspl@linux.vnet.ibm.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent 692c7f6d
...@@ -801,6 +801,8 @@ class Stats(object): ...@@ -801,6 +801,8 @@ class Stats(object):
LABEL_WIDTH = 40 LABEL_WIDTH = 40
NUMBER_WIDTH = 10 NUMBER_WIDTH = 10
DELAY_INITIAL = 0.25
DELAY_REGULAR = 3.0
class Tui(object): class Tui(object):
...@@ -856,13 +858,14 @@ class Tui(object): ...@@ -856,13 +858,14 @@ class Tui(object):
"""Propagates pid selection to stats object.""" """Propagates pid selection to stats object."""
self.stats.pid_filter = pid self.stats.pid_filter = pid
def refresh(self, sleeptime): def refresh_header(self, pid=None):
"""Refreshes on-screen data.""" """Refreshes the header."""
if pid is None:
pid = self.stats.pid_filter
self.screen.erase() self.screen.erase()
if self.stats.pid_filter > 0: if pid > 0:
self.screen.addstr(0, 0, 'kvm statistics - pid {0}' self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
.format(self.stats.pid_filter), .format(pid), curses.A_BOLD)
curses.A_BOLD)
else: else:
self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD) self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
self.screen.addstr(2, 1, 'Event') self.screen.addstr(2, 1, 'Event')
...@@ -870,7 +873,13 @@ class Tui(object): ...@@ -870,7 +873,13 @@ class Tui(object):
len('Total'), 'Total') len('Total'), 'Total')
self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 - self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
len('Current'), 'Current') len('Current'), 'Current')
self.screen.addstr(4, 1, 'Collecting data...')
self.screen.refresh()
def refresh_body(self, sleeptime):
row = 3 row = 3
self.screen.move(row, 0)
self.screen.clrtobot()
stats = self.stats.get() stats = self.stats.get()
def sortkey(x): def sortkey(x):
...@@ -914,10 +923,12 @@ class Tui(object): ...@@ -914,10 +923,12 @@ class Tui(object):
regex = self.screen.getstr() regex = self.screen.getstr()
curses.noecho() curses.noecho()
if len(regex) == 0: if len(regex) == 0:
self.refresh_header()
return return
try: try:
re.compile(regex) re.compile(regex)
self.stats.fields_filter = regex self.stats.fields_filter = regex
self.refresh_header()
return return
except re.error: except re.error:
continue continue
...@@ -944,37 +955,38 @@ class Tui(object): ...@@ -944,37 +955,38 @@ class Tui(object):
try: try:
pid = int(pid) pid = int(pid)
if pid != 0 and not os.path.isdir(os.path.join('/proc/',
if pid == 0: str(pid))):
self.update_pid(pid) continue
break self.refresh_header(pid)
else: self.update_pid(pid)
if not os.path.isdir(os.path.join('/proc/', str(pid))): break
continue
else:
self.update_pid(pid)
break
except ValueError: except ValueError:
continue continue
def show_stats(self): def show_stats(self):
"""Refreshes the screen and processes user input.""" """Refreshes the screen and processes user input."""
sleeptime = 0.25 sleeptime = DELAY_INITIAL
self.refresh_header()
while True: while True:
self.refresh(sleeptime) self.refresh_body(sleeptime)
curses.halfdelay(int(sleeptime * 10)) curses.halfdelay(int(sleeptime * 10))
sleeptime = 3.0 sleeptime = DELAY_REGULAR
try: try:
char = self.screen.getkey() char = self.screen.getkey()
if char == 'x': if char == 'x':
self.refresh_header()
self.update_drilldown() self.update_drilldown()
sleeptime = DELAY_INITIAL
if char == 'q': if char == 'q':
break break
if char == 'f': if char == 'f':
self.show_filter_selection() self.show_filter_selection()
sleeptime = DELAY_INITIAL
if char == 'p': if char == 'p':
self.show_vm_selection() self.show_vm_selection()
sleeptime = DELAY_INITIAL
except KeyboardInterrupt: except KeyboardInterrupt:
break break
except curses.error: except curses.error:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment