feat(cli): support float number as snapshot interval (>= 0.25s)

This commit is contained in:
Xuehai Pan 2023-04-07 09:03:51 +00:00
parent c883884073
commit ce66cac61f
7 changed files with 43 additions and 8 deletions

View file

@ -31,13 +31,13 @@ def parse_arguments() -> argparse.Namespace:
colored('heavy', 'red'),
)
def posint(argstring: str) -> int:
num = int(argstring)
def posfloat(argstring: str) -> float:
num = float(argstring)
if num <= 0:
raise ValueError
return num
posint.__name__ = 'positive integer'
posfloat.__name__ = 'positive float'
parser = argparse.ArgumentParser(
prog='nvitop',
@ -88,7 +88,7 @@ def parse_arguments() -> argparse.Namespace:
parser.add_argument(
'--interval',
dest='interval',
type=posint,
type=posfloat,
default=None,
metavar='SEC',
help='Process status update interval in seconds. (default: 2)',
@ -223,6 +223,12 @@ def parse_arguments() -> argparse.Namespace:
args = parser.parse_args()
if args.interval is not None and args.interval < 0.25:
parser.error(
f'the interval {args.interval:0.2g}s is too short, which may cause performance issues. '
f'Expected 1/4 or higher.',
)
if not args.colorful:
args.colorful = 'colorful' in NVITOP_MONITOR_MODE and 'plain' not in NVITOP_MONITOR_MODE
if not args.light:

View file

@ -14,7 +14,7 @@ from nvitop.version import __version__
class DevicePanel(Displayable): # pylint: disable=too-many-instance-attributes
NAME = 'device'
SNAPSHOT_INTERVAL = 0.67
SNAPSHOT_INTERVAL = 0.5
def __init__(self, devices, compact, win, root):
super().__init__(win, root)
@ -127,6 +127,16 @@ class DevicePanel(Displayable): # pylint: disable=too-many-instance-attributes
with self.snapshot_lock:
self._snapshots = snapshots
@classmethod
def set_snapshot_interval(cls, interval):
assert interval > 0.0
interval = float(interval)
cls.SNAPSHOT_INTERVAL = min(interval / 3.0, 1.0)
cls.take_snapshots = ttl_cache(ttl=interval)(
cls.take_snapshots.__wrapped__, # pylint: disable=no-member
)
@ttl_cache(ttl=1.0)
def take_snapshots(self):
snapshots = [device.as_snapshot() for device in self.all_devices]

View file

@ -165,6 +165,13 @@ class HostPanel(Displayable): # pylint: disable=too-many-instance-attributes
format=lambda x: f'{prefix}GPU UTL: {percentage(x)}',
)
@classmethod
def set_snapshot_interval(cls, interval):
assert interval > 0.0
interval = float(interval)
cls.SNAPSHOT_INTERVAL = min(interval / 3.0, 0.5)
def take_snapshots(self):
host.cpu_percent()
host.virtual_memory()

View file

@ -34,7 +34,7 @@ Order = namedtuple('Order', ['key', 'reverse', 'offset', 'column', 'previous', '
class ProcessPanel(Displayable): # pylint: disable=too-many-instance-attributes
NAME = 'process'
SNAPSHOT_INTERVAL = 0.67
SNAPSHOT_INTERVAL = 0.5
ORDERS = {
'natural': Order(

View file

@ -269,6 +269,13 @@ class ProcessMetricsScreen(Displayable): # pylint: disable=too-many-instance-at
self.selection.process = value
self.enable()
@classmethod
def set_snapshot_interval(cls, interval):
assert interval > 0.0
interval = float(interval)
cls.SNAPSHOT_INTERVAL = min(interval / 3.0, 1.0)
def take_snapshots(self):
with self.snapshot_lock:
if not self.selection.is_set() or not self.enabled:

View file

@ -216,7 +216,7 @@ class TreeNode: # pylint: disable=too-many-instance-attributes
class TreeViewScreen(Displayable): # pylint: disable=too-many-instance-attributes
NAME = 'treeview'
SNAPSHOT_INTERVAL = 0.67
SNAPSHOT_INTERVAL = 0.5
def __init__(self, win, root):
super().__init__(win, root)

View file

@ -77,6 +77,11 @@ class UI(DisplayableContainer): # pylint: disable=too-many-instance-attributes
self.add_child(self.help_screen)
if interval is not None:
if interval < 1.0:
self.main_screen.device_panel.set_snapshot_interval(interval)
self.main_screen.host_panel.set_snapshot_interval(interval)
if interval < 0.5:
self.process_metrics_screen.set_snapshot_interval(interval)
self.main_screen.process_panel.set_snapshot_interval(interval)
self.treeview_screen.set_snapshot_interval(interval)
@ -190,7 +195,7 @@ class UI(DisplayableContainer): # pylint: disable=too-many-instance-attributes
self.redraw()
self.handle_input()
if time.monotonic() - self.last_input_time > 1.0:
time.sleep(0.25)
time.sleep(0.2)
except BreakLoop:
break