Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+30 −18
Original line number Diff line number Diff line
@@ -801,6 +801,8 @@ class Stats(object):

LABEL_WIDTH = 40
NUMBER_WIDTH = 10
DELAY_INITIAL = 0.25
DELAY_REGULAR = 3.0


class Tui(object):
@@ -856,13 +858,14 @@ class Tui(object):
        """Propagates pid selection to stats object."""
        self.stats.pid_filter = pid

    def refresh(self, sleeptime):
        """Refreshes on-screen data."""
    def refresh_header(self, pid=None):
        """Refreshes the header."""
        if pid is None:
            pid = self.stats.pid_filter
        self.screen.erase()
        if self.stats.pid_filter > 0:
        if pid > 0:
            self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
                               .format(self.stats.pid_filter),
                               curses.A_BOLD)
                               .format(pid), curses.A_BOLD)
        else:
            self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
        self.screen.addstr(2, 1, 'Event')
@@ -870,7 +873,13 @@ class Tui(object):
                           len('Total'), 'Total')
        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
                           len('Current'), 'Current')
        self.screen.addstr(4, 1, 'Collecting data...')
        self.screen.refresh()

    def refresh_body(self, sleeptime):
        row = 3
        self.screen.move(row, 0)
        self.screen.clrtobot()
        stats = self.stats.get()

        def sortkey(x):
@@ -914,10 +923,12 @@ class Tui(object):
            regex = self.screen.getstr()
            curses.noecho()
            if len(regex) == 0:
                self.refresh_header()
                return
            try:
                re.compile(regex)
                self.stats.fields_filter = regex
                self.refresh_header()
                return
            except re.error:
                continue
@@ -944,14 +955,10 @@ class Tui(object):

            try:
                pid = int(pid)

                if pid == 0:
                    self.update_pid(pid)
                    break
                else:
                    if not os.path.isdir(os.path.join('/proc/', str(pid))):
                if pid != 0 and not os.path.isdir(os.path.join('/proc/',
                                                               str(pid))):
                    continue
                    else:
                self.refresh_header(pid)
                self.update_pid(pid)
                break

@@ -960,21 +967,26 @@ class Tui(object):

    def show_stats(self):
        """Refreshes the screen and processes user input."""
        sleeptime = 0.25
        sleeptime = DELAY_INITIAL
        self.refresh_header()
        while True:
            self.refresh(sleeptime)
            self.refresh_body(sleeptime)
            curses.halfdelay(int(sleeptime * 10))
            sleeptime = 3.0
            sleeptime = DELAY_REGULAR
            try:
                char = self.screen.getkey()
                if char == 'x':
                    self.refresh_header()
                    self.update_drilldown()
                    sleeptime = DELAY_INITIAL
                if char == 'q':
                    break
                if char == 'f':
                    self.show_filter_selection()
                    sleeptime = DELAY_INITIAL
                if char == 'p':
                    self.show_vm_selection()
                    sleeptime = DELAY_INITIAL
            except KeyboardInterrupt:
                break
            except curses.error: