From 3358c807a0002dc8626626053442c236b33122f1 Mon Sep 17 00:00:00 2001 From: Martinez Date: Thu, 6 Oct 2016 11:42:15 +0200 Subject: [PATCH] Gracefully degrade under load, fixes #2 --- libexec/render.py | 230 ++++++++++++++++++++++++---------------------- 1 file changed, 120 insertions(+), 110 deletions(-) diff --git a/libexec/render.py b/libexec/render.py index 1d62353..f9714eb 100755 --- a/libexec/render.py +++ b/libexec/render.py @@ -268,14 +268,15 @@ class PathPart(Part): """ /path/to/cwd - Contructs a list of Dirs from the root to CWD. When fit is called, some Dirs may be shortened. + Contructs a list of Dirs from the root to CWD. When shrink_fit is called, some Dirs may be shortened. """ - def __init__(self, settings): + + def __init__(self, settings, overloaded): Part.__init__(self) self.term_width = settings.term_width self.dirs = [] - homes = dict(list_homes()) + homes = {} if overloaded else dict(list_homes()) dirs = settings.cwd.split("/")[1:] path = "" @@ -490,126 +491,135 @@ class StatsPart(Part): # tasks self.fragments.append("%d " %(sysload.tasks_total)) - # memory (and swap, if used) - mem_total = 0 - mem_free = 0 - swap_total = 0 - swap_free = 0 - - # MemAvailable is not available on = settings.load_error: + self.fragments.append(" | ") self.fragments.append(style_color(COLOR_ERROR)) self.fragments.append(style_bold()) - self.fragments.append("❌ 2**20: - self.fragments.append(style_color(COLOR_MEMSWAP)) - self.fragments.append(" s") - self.fragments.append(style_bold()) - self.fragments.append(style_color(settings.get_space_color(swap_free, swap_total))) - swap_free_si = si_number(swap_free) - self.fragments.append(space_string(swap_free) %(swap_free_si[0], swap_free_si[1])) + self.fragments.append("⚠ OVERLOAD ⚠ ") self.fragments.append(style_reset()) - # mountpoints - names = [] - first_mountpoint = True - - with open("/proc/self/mounts") as f: - for line in f: - _, dir, type, options, *rest = line.split() - - # skip non-storage mounts - if type in MOUNT_IGNORE_FS: - continue - - if any([dir.startswith(d) for d in MOUNT_IGNORE_DIR]): - continue - - if "rw" not in options.split(","): - continue - - # /proc/self/mounts uses a literal \040 string to escape spaces - dir = dir.replace("\\040", " ") - - basename = os.path.basename(dir) - - if basename: - short_name = " " + else: + # memory (and swap, if used) + mem_total = 0 + mem_free = 0 + swap_total = 0 + swap_free = 0 + + # MemAvailable is not available on 2**20: + self.fragments.append(style_color(COLOR_MEMSWAP)) + self.fragments.append(" s") + self.fragments.append(style_bold()) + self.fragments.append(style_color(settings.get_space_color(swap_free, swap_total))) + swap_free_si = si_number(swap_free) + self.fragments.append(space_string(swap_free) %(swap_free_si[0], swap_free_si[1])) + self.fragments.append(style_reset()) + + # mountpoints + names = [] + first_mountpoint = True + + with open("/proc/self/mounts") as f: + for line in f: + _, dir, type, options, *rest = line.split() - for c in basename: - short_name += c - - if short_name not in names: - break - else: - short_name = " /" - - # handle btrfs separately - if type == "btrfs": - btrfs_raw = command(["/sbin/btrfs", "fi", "usage", "-b", dir]) - - for line in btrfs_raw.split("\n"): - if "Device size" in line: - stor_total = int(line.split()[-1]) - elif "Free" in line: - stor_free = int(line.split()[-3]) - break - - else: - try: - stat = os.statvfs(dir) - except PermissionError: + # skip non-storage mounts + if type in MOUNT_IGNORE_FS: continue - stor_total = stat.f_blocks * stat.f_bsize - stor_free = stat.f_bavail * stat.f_bsize - - # ignore virtual filesystems - if stor_total == 0: - continue - - if first_mountpoint: - self.fragments.append(" |") - first_mountpoint = False - - self.fragments.append(short_name) - self.fragments.append(style_bold()) - self.fragments.append(style_color(settings.get_space_color(stor_free, stor_total))) - stor_free_si = si_number(stor_free) - self.fragments.append(space_string(stor_free) %(stor_free_si[0], stor_free_si[1])) - self.fragments.append(style_reset()) + if any([dir.startswith(d) for d in MOUNT_IGNORE_DIR]): + continue + + if "rw" not in options.split(","): + continue + + # /proc/self/mounts uses a literal \040 string to escape spaces + dir = dir.replace("\\040", " ") + + basename = os.path.basename(dir) + + if basename: + short_name = " " + + for c in basename: + short_name += c + + if short_name not in names: + break + else: + short_name = " /" + + # handle btrfs separately + if type == "btrfs": + btrfs_raw = command(["/sbin/btrfs", "fi", "usage", "-b", dir]) + + for line in btrfs_raw.split("\n"): + if "Device size" in line: + stor_total = int(line.split()[-1]) + elif "Free" in line: + stor_free = int(line.split()[-3]) + break + + else: + try: + stat = os.statvfs(dir) + except PermissionError: + continue + + stor_total = stat.f_blocks * stat.f_bsize + stor_free = stat.f_bavail * stat.f_bsize + + # ignore virtual filesystems + if stor_total == 0: + continue + + if first_mountpoint: + self.fragments.append(" |") + first_mountpoint = False + + self.fragments.append(short_name) + self.fragments.append(style_bold()) + self.fragments.append(style_color(settings.get_space_color(stor_free, stor_total))) + stor_free_si = si_number(stor_free) + self.fragments.append(space_string(stor_free) %(stor_free_si[0], stor_free_si[1])) + self.fragments.append(style_reset()) if __name__ == "__main__": settings = Settings(sys.argv) sysload = Sysload() + overloaded = sysload.load1 >= settings.load_error lp = LoginPart(settings, sysload) - pp = PathPart(settings) - gp = GitPart() + pp = PathPart(settings, overloaded) + gp = "" if overloaded else GitPart() vp = VirtualEnvPart() wp = WineprefixPart() pad = Padding(settings.term_width)