diff --git a/bazel/wrapper_hook/BUILD.bazel b/bazel/wrapper_hook/BUILD.bazel index efb402bd4b3..dea64c09a7e 100644 --- a/bazel/wrapper_hook/BUILD.bazel +++ b/bazel/wrapper_hook/BUILD.bazel @@ -4,6 +4,7 @@ py_library( name = "wrapper_hook", srcs = [ "autogenerated_targets.py", + "check_resources.py", "compiledb.py", "engflow_check.py", "generate_common_bes_bazelrc.py", @@ -14,6 +15,7 @@ py_library( "set_mongo_variables.py", "wrapper_debug.py", "wrapper_hook.py", + "wrapper_util.py", ], visibility = ["//visibility:public"], ) diff --git a/bazel/wrapper_hook/check_resources.py b/bazel/wrapper_hook/check_resources.py new file mode 100644 index 00000000000..95eb16a6531 --- /dev/null +++ b/bazel/wrapper_hook/check_resources.py @@ -0,0 +1,25 @@ +import pathlib +import sys + +REPO_ROOT = str(pathlib.Path(__file__).parent.parent.parent) +sys.path.append(REPO_ROOT) + +from bazel.wrapper_hook.wrapper_debug import wrapper_debug +from bazel.wrapper_hook.wrapper_util import memory_info + + +def check_resource(): + """Check if user machine is using optimal resources.""" + wrapper_debug(f"Check if user machine is using optimal resources {REPO_ROOT}") + mem_available = memory_info("MemAvailable") + wrapper_debug(f"Available memory: {mem_available} GB") + + if mem_available == "Unknown": + print("Warning: Unable to determine available memory.") + return + + if float(mem_available) < 6.0: + print( + f"Warning: Available memory is low ({mem_available} GB). " + "For optimal performance, it is recommended to have at least 8 GB of available memory." + ) diff --git a/bazel/wrapper_hook/generate_common_bes_bazelrc.py b/bazel/wrapper_hook/generate_common_bes_bazelrc.py index 2d5e4cc88b3..a43876d5146 100644 --- a/bazel/wrapper_hook/generate_common_bes_bazelrc.py +++ b/bazel/wrapper_hook/generate_common_bes_bazelrc.py @@ -1,15 +1,19 @@ import base64 import hashlib import json -import multiprocessing import os import pathlib -import platform import socket import sys import git +from bazel.wrapper_hook.wrapper_util import ( + cpu_info, + filesystem_info, + memory_info, +) + def write_workstation_bazelrc(args): repo_root = pathlib.Path(os.path.abspath(__file__)).parent.parent.parent @@ -78,49 +82,10 @@ def write_workstation_bazelrc(args): pass # Collect system resource information - cpu_count = "Unknown" - total_memory_gb = "Unknown" - available_memory_gb = "Unknown" - filesystem_type = "Unknown" - - # CPU count - works on all platforms - try: - cpu_count = str(os.cpu_count() or multiprocessing.cpu_count()) - except Exception: - pass - - # Memory - Linux only - try: - if platform.system() == "Linux": - with open("/proc/meminfo", "r") as f: - for line in f: - if line.startswith("MemTotal:"): - kb = int(line.split()[1]) - total_memory_gb = str(round(kb / (1024 * 1024), 2)) - elif line.startswith("MemAvailable:"): - kb = int(line.split()[1]) - available_memory_gb = str(round(kb / (1024 * 1024), 2)) - except Exception: - pass - - # Filesystem type - Linux only - try: - if platform.system() == "Linux": - repo_path = str(repo_root) - with open("/proc/mounts", "r") as f: - best_mountpoint_len = 0 - for line in f: - parts = line.split() - if len(parts) >= 3: - mountpoint, fstype = parts[1], parts[2] - if ( - repo_path.startswith(mountpoint) - and len(mountpoint) > best_mountpoint_len - ): - filesystem_type = fstype - best_mountpoint_len = len(mountpoint) - except Exception: - pass + cpu_count = cpu_info() # CPU count - works on all platforms + total_memory_gb = memory_info("MemTotal") # Total memory - Linux only + available_memory_gb = memory_info("MemAvailable") # Available memory - Linux only + filesystem_type, best_mountpoint_len = filesystem_info() # Filesystem type - Linux only filtered_args = args[1:] if "--" in filtered_args: diff --git a/bazel/wrapper_hook/wrapper_hook.py b/bazel/wrapper_hook/wrapper_hook.py index faa466713b0..ea1e7c0af46 100644 --- a/bazel/wrapper_hook/wrapper_hook.py +++ b/bazel/wrapper_hook/wrapper_hook.py @@ -21,6 +21,7 @@ def main(): from bazel.auto_header.gen_all_headers import spawn_all_headers_thread from bazel.wrapper_hook.autogenerated_targets import autogenerate_targets + from bazel.wrapper_hook.check_resources import check_resource from bazel.wrapper_hook.engflow_check import engflow_auth from bazel.wrapper_hook.generate_common_bes_bazelrc import write_workstation_bazelrc @@ -59,6 +60,7 @@ def main(): write_mongo_variables_bazelrc(args) # Disable git age check for now, to avoid issues wth merge commits # git_age_check() + check_resource() try: args = test_runner_interface( diff --git a/bazel/wrapper_hook/wrapper_util.py b/bazel/wrapper_hook/wrapper_util.py new file mode 100644 index 00000000000..1c8ab849f57 --- /dev/null +++ b/bazel/wrapper_hook/wrapper_util.py @@ -0,0 +1,66 @@ +"""Wrapper utilities for the Bazel build system.""" + +import multiprocessing +import os +import pathlib +import platform + +from bazel.wrapper_hook.wrapper_debug import wrapper_debug + +_UNKNOWN = "Unknown" +_REPO_ROOT = str(pathlib.Path(__file__).parent.parent.parent) + + +def cpu_info() -> str: + """CPU count - works on all platforms""" + try: + return str(os.cpu_count() or multiprocessing.cpu_count()) + except Exception as _e: + wrapper_debug(f"Failed to get CPU count {_e}") + return _UNKNOWN + + +def memory_info(mem_type: str) -> str: + """Memory - Linux only""" + memory_gb = _UNKNOWN + + if not platform.system() == "Linux": + return _UNKNOWN + + try: + with open("/proc/meminfo", "r") as f: + for line in f: + if line.startswith(f"{mem_type}:"): + kb = int(line.split()[1]) + memory_gb = str(round(kb / (1024 * 1024), 2)) + break + except Exception as _e: + wrapper_debug(f"Failed to get memory info {_e}") + return _UNKNOWN + + return memory_gb + + +def filesystem_info() -> tuple[str, int]: + """Filesystem type - Linux only""" + fs_type = (_UNKNOWN, 0) + if not platform.system() == "Linux": + return (_UNKNOWN, 0) + + try: + repo_path = _REPO_ROOT + with open("/proc/mounts", "r") as f: + best_mountpoint_len = 0 + for line in f: + parts = line.split() + if len(parts) >= 3: + mountpoint, fstype = parts[1], parts[2] + if repo_path.startswith(mountpoint) and len(mountpoint) > best_mountpoint_len: + filesystem_type = fstype + best_mountpoint_len = len(mountpoint) + fs_type = (filesystem_type, best_mountpoint_len) + except Exception as _e: + wrapper_debug(f"Failed to get filesystem type {_e}") + return (_UNKNOWN, 0) + + return fs_type