Skip to content

⚡ Bolt: Optimized telemetry state caching and secret redaction#169

Open
heidi-dang wants to merge 1 commit intofeat/bootstrap-scaffoldfrom
bolt/telemetry-optimizations-7177115978715405411
Open

⚡ Bolt: Optimized telemetry state caching and secret redaction#169
heidi-dang wants to merge 1 commit intofeat/bootstrap-scaffoldfrom
bolt/telemetry-optimizations-7177115978715405411

Conversation

@heidi-dang
Copy link
Copy Markdown
Owner

Optimized the telemetry module in heidi_engine/telemetry.py by fixing a NameError and implementing several performance-critical caching and regex optimizations. Specifically, I added a write-through cache for the run state, pre-compiled regex patterns for secret redaction, and implemented mtime-based caching for the pricing configuration. These changes measurably reduce disk I/O and CPU overhead in the telemetry hot-paths.


PR created automatically by Jules for task 7177115978715405411 started by @heidi-dang

- Fixed NameError in get_state by removing redundant/broken cache check.
- Implemented write-through caching in save_state to eliminate disk I/O on subsequent reads.
- Pre-compiled SECRET_PATTERNS to reduce regex overhead in redact_secrets.
- Added thread-safe mtime-based caching for load_pricing_config with 5s negative cache for missing files.
- Ensured cache isolation using deepcopy for all pricing configuration returns.

Performance Impact:
- redact_secrets (with secrets): ~34% improvement (0.24s -> 0.16s for 10k calls).
- get_state (cache hit): ~28ms for 10k calls (vs disk I/O).
- load_pricing_config: significant reduction in syscalls and JSON parsing.
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the performance and efficiency of the telemetry module by introducing several critical optimizations. It addresses potential NameError issues and focuses on reducing disk I/O and CPU overhead. Key improvements include pre-compiling regex patterns for faster secret redaction, implementing robust mtime-based caching for pricing configurations, and establishing a write-through cache for telemetry run states. These changes aim to make telemetry operations more responsive and less resource-intensive.

Highlights

  • Optimized Secret Redaction: Pre-compiled regex patterns for secret redaction were introduced, significantly reducing CPU overhead in the redact_secrets hot-path by avoiding repeated compilation.
  • Mtime-Based Pricing Configuration Caching: A thread-safe, mtime-based caching mechanism was implemented for pricing.json, including negative caching for non-existent files, to minimize redundant disk I/O during pricing lookups.
  • Write-Through Telemetry State Caching: The telemetry run state caching was refactored to use a write-through approach, ensuring consistency and reducing redundant disk I/O during frequent state updates and reads.
  • Performance Benchmarking Script: A new script was added to benchmark the performance improvements in secret redaction, pricing configuration loading, and state caching, providing measurable validation of the optimizations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several valuable performance optimizations to the telemetry module, such as pre-compiling regular expressions for secret redaction and implementing caching for pricing configurations and run state. The changes are well-reasoned and are accompanied by a new benchmark script to validate the improvements. My review focuses on a couple of areas where the implementation can be made more robust and Pythonic. Specifically, I've suggested a refinement to the caching logic in load_pricing_config and an improvement to the timer used in the new benchmark script for more accurate measurements.

Comment thread heidi_engine/telemetry.py
Comment on lines 512 to 529
try:
with open(pricing_file) as f:
custom = json.load(f)
pricing.update(custom)
if pricing_file.exists():
mtime = pricing_file.stat().st_mtime
if abs_path in _pricing_cache and _pricing_mtimes.get(abs_path) == mtime:
return copy.deepcopy(_pricing_cache[abs_path])

with open(pricing_file) as f:
pricing = DEFAULT_PRICING.copy()
custom = json.load(f)
pricing.update(custom)
_pricing_cache[abs_path] = pricing
_pricing_mtimes[abs_path] = mtime
return copy.deepcopy(pricing)
else:
_pricing_mtimes[abs_path] = -1.0
_pricing_check_ts[abs_path] = now
except Exception as e:
print(f"[WARN] Failed to load pricing config: {e}", file=sys.stderr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation for loading the pricing configuration uses a 'Look Before You Leap' (LBYL) approach with pricing_file.exists(). This can be simplified and made more robust by adopting an 'Easier to Ask for Forgiveness than Permission' (EAFP) approach using a try...except FileNotFoundError block. This change would improve readability, be more Pythonic, and avoid a potential race condition between checking for the file's existence and opening it, while also being slightly more performant by reducing a syscall.

Suggested change
try:
with open(pricing_file) as f:
custom = json.load(f)
pricing.update(custom)
if pricing_file.exists():
mtime = pricing_file.stat().st_mtime
if abs_path in _pricing_cache and _pricing_mtimes.get(abs_path) == mtime:
return copy.deepcopy(_pricing_cache[abs_path])
with open(pricing_file) as f:
pricing = DEFAULT_PRICING.copy()
custom = json.load(f)
pricing.update(custom)
_pricing_cache[abs_path] = pricing
_pricing_mtimes[abs_path] = mtime
return copy.deepcopy(pricing)
else:
_pricing_mtimes[abs_path] = -1.0
_pricing_check_ts[abs_path] = now
except Exception as e:
print(f"[WARN] Failed to load pricing config: {e}", file=sys.stderr)
try:
mtime = pricing_file.stat().st_mtime
if abs_path in _pricing_cache and _pricing_mtimes.get(abs_path) == mtime:
return copy.deepcopy(_pricing_cache[abs_path])
with open(pricing_file) as f:
pricing = DEFAULT_PRICING.copy()
custom = json.load(f)
pricing.update(custom)
_pricing_cache[abs_path] = pricing
_pricing_mtimes[abs_path] = mtime
return copy.deepcopy(pricing)
except FileNotFoundError:
_pricing_mtimes[abs_path] = -1.0
_pricing_check_ts[abs_path] = now
except Exception as e:
print(f"[WARN] Failed to load pricing config: {e}", file=sys.stderr)

Comment on lines +18 to +21
start = time.time()
for _ in range(10000):
redact_secrets(text_no_secrets)
end = time.time()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For more accurate performance measurement, it's better to use time.perf_counter() instead of time.time(). time.perf_counter() provides a high-resolution monotonic clock that is not affected by system time changes, making it ideal for benchmarking short-duration operations. This change should be applied to all benchmarks in this file.

Suggested change
start = time.time()
for _ in range(10000):
redact_secrets(text_no_secrets)
end = time.time()
start = time.perf_counter()
for _ in range(10000):
redact_secrets(text_no_secrets)
end = time.perf_counter()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant