-
Notifications
You must be signed in to change notification settings - Fork 36
⚡ Bolt: optimize PriorityEngine with regex caching and I/O throttling #527
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
139a4c1
44d1a41
2bea8c2
59abbc9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,7 @@ class AdaptiveWeights: | |||||
| _instance = None | ||||||
| _weights = None | ||||||
| _last_loaded = 0 | ||||||
| _last_check_time = 0 | ||||||
|
|
||||||
| def __new__(cls): | ||||||
| if cls._instance is None: | ||||||
|
|
@@ -40,8 +41,11 @@ def _load_weights(self): | |||||
| self._weights = {} | ||||||
|
|
||||||
| def _check_reload(self): | ||||||
| # Optimization: Checking mtime is fast (stat call). | ||||||
| self._load_weights() | ||||||
| # Optimization: 5-second throttle to prevent excessive I/O in hot paths. | ||||||
| now = time.time() | ||||||
|
||||||
| now = time.time() | |
| now = time.monotonic() |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,7 +13,26 @@ class PriorityEngine: | |||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self): | ||||||||||||||||||||||||||||||||||||||||||||||
| # We no longer hardcode values here. | ||||||||||||||||||||||||||||||||||||||||||||||
| # They are fetched dynamically from AdaptiveWeights on each analysis. | ||||||||||||||||||||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||||||||||||||||||||
| self._regex_cache = [] | ||||||||||||||||||||||||||||||||||||||||||||||
| self._last_loaded_time = 0 | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def _get_compiled_patterns(self): | ||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||
| Retrieves pre-compiled regex patterns for urgency calculations. | ||||||||||||||||||||||||||||||||||||||||||||||
| Invalidates cache if adaptive weights have been updated. | ||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||
| # Ensure latest weights are at least checked for reload (subject to throttling) | ||||||||||||||||||||||||||||||||||||||||||||||
| adaptive_weights._check_reload() | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| current_load_time = adaptive_weights._last_loaded | ||||||||||||||||||||||||||||||||||||||||||||||
| if not self._regex_cache or current_load_time > self._last_loaded_time: | ||||||||||||||||||||||||||||||||||||||||||||||
| urgency_patterns = adaptive_weights.get_urgency_patterns() | ||||||||||||||||||||||||||||||||||||||||||||||
| self._regex_cache = [ | ||||||||||||||||||||||||||||||||||||||||||||||
| (re.compile(pattern, re.IGNORECASE), weight) | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| (re.compile(pattern, re.IGNORECASE), weight) | |
| (re.compile(pattern), weight) |
Copilot
AI
Mar 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PriorityEngine is reaching into adaptive_weights internals (_check_reload() and _last_loaded). This tight coupling makes future refactors of AdaptiveWeights risky and bypasses its public API. Consider adding a small public method (e.g., get_urgency_patterns_compiled() or get_weights_version()/last_loaded()) so cache invalidation doesn’t depend on private members.
| Invalidates cache if adaptive weights have been updated. | |
| """ | |
| # Ensure latest weights are at least checked for reload (subject to throttling) | |
| adaptive_weights._check_reload() | |
| current_load_time = adaptive_weights._last_loaded | |
| if not self._regex_cache or current_load_time > self._last_loaded_time: | |
| urgency_patterns = adaptive_weights.get_urgency_patterns() | |
| self._regex_cache = [ | |
| (re.compile(pattern, re.IGNORECASE), weight) | |
| for pattern, weight in urgency_patterns | |
| ] | |
| self._last_loaded_time = current_load_time | |
| This implementation only relies on the public AdaptiveWeights API | |
| and does not access its private internals, to avoid tight coupling. | |
| """ | |
| urgency_patterns = adaptive_weights.get_urgency_patterns() | |
| self._regex_cache = [ | |
| (re.compile(pattern, re.IGNORECASE), weight) | |
| for pattern, weight in urgency_patterns | |
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,12 @@ a2wsgi | |
| python-jose[cryptography] | ||
| passlib[bcrypt] | ||
| bcrypt<4.0.0 | ||
| python-dotenv | ||
| SpeechRecognition | ||
| pydub | ||
| googletrans==4.0.2 | ||
| langdetect | ||
| async_lru | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify whether async_lru is actually imported or referenced anywhere in the backend.
rg -nP --type=py -C2 '^\s*(from\s+async_lru\s+import|import\s+async_lru\b|@alru_cache\b|alru_cache\s*\()' backend
# Show the deployment-related comments that currently claim async_lru was removed/replaced.
rg -n -C2 'async[-_ ]lru|manual cache|avoid .*Render|replace async_lru' backendRepository: RohanExploit/VishwaGuru Length of output: 1494 Remove
🤖 Prompt for AI Agents |
||
| indic-nlp-library | ||
| numpy | ||
| scikit-learn | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,13 @@ | ||
| INFO: Will watch for changes in these directories: ['E:\\projects\\VishwaGuru\\VishwaGuru'] | ||
| INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) | ||
| INFO: Started reloader process [42100] using StatReload | ||
| 2026-03-09 02:00:56,311 - backend.adaptive_weights - INFO - Adaptive weights loaded/reloaded. | ||
| WARNING: StatReload detected changes in 'backend\main.py'. Reloading... | ||
|
|
||
| 2026-03-09 15:06:36,764 - backend.adaptive_weights - INFO - Adaptive weights loaded/reloaded. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: This change commits nondeterministic runtime log output (timestamps/PIDs), which creates noisy diffs and makes meaningful changes harder to review. Prefer removing this artifact from source control or normalizing dynamic fields in the tracked output. Prompt for AI agents |
||
| 2026-03-09 15:06:36,834 - backend.rag_service - INFO - Loaded 5 civic policies for RAG. | ||
| /home/jules/.pyenv/versions/3.12.12/lib/python3.12/site-packages/pydub/utils.py:170: RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work | ||
| warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning) | ||
| 2026-03-09 15:06:37,177 - backend.main - WARNING - FRONTEND_URL not set. Defaulting to http://localhost:5173 for development. | ||
| INFO: Started server process [9775] | ||
| INFO: Waiting for application startup. | ||
| INFO: Application startup complete. | ||
| INFO: Uvicorn running on http://0.0.0.0:10000 (Press CTRL+C to quit) | ||
| INFO: Shutting down | ||
| INFO: Waiting for application shutdown. | ||
| INFO: Application shutdown complete. | ||
| INFO: Finished server process [9775] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,29 @@ | ||||||||||||||||||||||||||
| import time | ||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||
| import re | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add project root to sys.path | ||||||||||||||||||||||||||
| sys.path.append(os.getcwd()) | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Using Prompt for AI agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| from backend.priority_engine import priority_engine | ||||||||||||||||||||||||||
| from backend.adaptive_weights import adaptive_weights | ||||||||||||||||||||||||||
|
Comment on lines
+4
to
+10
|
||||||||||||||||||||||||||
| import re | |
| # Add project root to sys.path | |
| sys.path.append(os.getcwd()) | |
| from backend.priority_engine import priority_engine | |
| from backend.adaptive_weights import adaptive_weights | |
| # Add project root to sys.path | |
| sys.path.append(os.getcwd()) | |
| from backend.priority_engine import priority_engine |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Use a monotonic clock for throttle intervals; wall-clock adjustments can break reload timing.
Prompt for AI agents