#!/usr/bin/env python3 # Copyright (C) 2024-2026 Whiterun LLC, # This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later., # A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html import os import sys import re """ Disallow blocking write pool access (_w.get()) in RPC handlers. Blocking .get() calls on write pools can exhaust Rocket's thread pool if a background task holds the write lock for an extended period. All threads waiting on .get() will block, causing the entire API to hang. Use try_get() instead, which returns None immediately if the lock is unavailable. OK (non-blocking): if let Some(cw) = dbp.cauldron_w.try_get() { ... } NOT OK (blocks thread, can cause API hang): let cw = dbp.cauldron_w.get()?; """ OUR_PATH = os.path.dirname(os.path.realpath(__file__)) # Pattern to detect blocking write pool access: something_w.get() FORBIDDEN_PATTERN = re.compile(r"\b\w+_w\.get\(\)") def check_file_for_blocking_write_lock(file_path): """Check if the file contains blocking _w.get() calls outside of test modules.""" violations = [] with open(file_path, 'r', encoding='utf-8') as file: for line_num, line in enumerate(file, 1): # Stop checking if we enter test module if re.search(r"\bmod tests \{", line): break if FORBIDDEN_PATTERN.search(line): violations.append((line_num, line.strip())) return violations def check_rpc_files(): """ Traverse src/rpc and check each .rs file for blocking write lock access. """ rpc_dir = os.path.join(OUR_PATH, "..", "src", "rpc") found_violations = False for root, dirs, files in os.walk(rpc_dir): for file in files: if file.endswith('.rs'): file_path = os.path.join(root, file) violations = check_file_for_blocking_write_lock(file_path) if violations: found_violations = True rel_path = os.path.relpath(file_path, os.path.join(OUR_PATH, "..")) for line_num, line in violations: print(f"{rel_path}:{line_num}: blocking _w.get() found") print(f" {line}") print(f" hint: use try_get() instead to avoid thread exhaustion") print() if found_violations: print("ERROR: Blocking write pool access found in RPC handlers.") print("This can cause API hangs if a background task holds the write lock.") sys.exit(1) else: print("OK") sys.exit(0) if __name__ == "__main__": check_rpc_files()