Skip to content

Comments

⚡ Bolt: Optimize config loading for plugin endpoints#104

Draft
Dexploarer wants to merge 1 commit intodevelopfrom
bolt-optimize-config-io-8380716501792575775
Draft

⚡ Bolt: Optimize config loading for plugin endpoints#104
Dexploarer wants to merge 1 commit intodevelopfrom
bolt-optimize-config-io-8380716501792575775

Conversation

@Dexploarer
Copy link
Owner

⚡ Bolt: Optimize config loading for plugin endpoints

💡 What:
Removed synchronous loadMilaidyConfig() calls from GET /api/plugins and GET /api/registry/plugins by leveraging the existing in-memory state.config. Explicitly reloads configuration only when it is modified via install/uninstall endpoints.

🎯 Why:
The previous implementation re-read the configuration file from disk on every request to /api/plugins, which blocked the event loop due to synchronous I/O. This was unnecessary as the server maintains the configuration state in memory.

📊 Impact:
Reduces I/O overhead and latency for plugin listing endpoints. Eliminates a synchronous blocking operation from the hot path of the API.

🔬 Measurement:
Verified with a reproduction test (src/api/repro_issue.test.ts) which confirmed that loadMilaidyConfig is no longer called on GET /api/plugins requests, whereas it was called previously.


PR created automatically by Jules for task 8380716501792575775 started by @Dexploarer

Optimized `GET /api/plugins` and `GET /api/registry/plugins` to use the in-memory `state.config` instead of synchronously reloading the configuration file from disk on every request.

Key changes:
- `src/services/plugin-installer.ts`: `listInstalledPlugins` now accepts an optional `config` object to bypass disk read.
- `src/api/server.ts`:
    - Updated `GET /api/plugins` to use `state.config`.
    - Updated `GET /api/registry/plugins` to pass `state.config`.
    - Added explicit config reloading in `POST /api/plugins/install` and `POST /api/plugins/uninstall` to keep `state.config` fresh after mutations.

This reduces latency for frequently accessed plugin endpoints and avoids blocking the event loop with synchronous file I/O.
@google-labs-jules
Copy link

👋 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.

@github-actions github-actions bot added the docs label Feb 20, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bolt-optimize-config-io-8380716501792575775

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @Dexploarer, 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 improves the performance and responsiveness of plugin-related API endpoints by refactoring how configuration data is accessed. It transitions from a synchronous, disk-based config loading mechanism on every request to leveraging an in-memory cache, thereby removing a blocking I/O operation from critical paths. The change ensures that the in-memory configuration is consistently updated following any modifications, such as plugin installations or uninstallations.

Highlights

  • Performance Optimization: Eliminated synchronous disk I/O for config loading in /api/plugins and /api/registry/plugins endpoints by utilizing the in-memory state.config.
  • Configuration Management: Implemented explicit reloading of the configuration after plugin installation and uninstallation to ensure state.config remains synchronized with disk changes.
  • Code Refinement: Updated the listInstalledPlugins utility to optionally accept an existing config object, reducing redundant config loading.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .jules/bolt.md
    • Updated a learning note regarding manual config invalidation for state.config in src/api/server.ts.
  • src/api/server.ts
    • Removed the synchronous loadMilaidyConfig() call from the GET /api/plugins endpoint, replacing it with the in-memory state.config.
    • Modified the GET /api/registry/plugins endpoint to pass state.config to the listInstalled function.
    • Added a try-catch block to reload state.config after a successful plugin installation.
    • Added a try-catch block to reload state.config after a successful plugin uninstallation.
  • src/services/plugin-installer.ts
    • Imported the MilaidyConfig type.
    • Modified the listInstalledPlugins function to accept an optional MilaidyConfig parameter, using it if provided, otherwise falling back to loadMilaidyConfig().
Activity
  • No human activity (comments, reviews, etc.) has been recorded for this pull request yet.
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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

Comment on lines +584 to 586
const cfg = config ?? loadMilaidyConfig();
const installs = cfg.plugins?.installs ?? {};

Choose a reason for hiding this comment

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

The function does not handle errors that may occur if loadMilaidyConfig() fails (e.g., due to a malformed or missing config file). This could result in an unhandled exception and crash the process.

Recommendation: Wrap the config loading and access in a try-catch block and return an empty array or a meaningful error if the config cannot be loaded safely.

Comment on lines +585 to 586
const installs = cfg.plugins?.installs ?? {};

Choose a reason for hiding this comment

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

There is a potential for inconsistent reads if the config is being modified concurrently by another operation (such as install or uninstall). This could result in a partial or outdated list of plugins being returned.

Recommendation: Consider implementing a read/write lock or other synchronization mechanism to ensure that config reads and writes are atomic and consistent.

Copy link

@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 optimizes configuration loading for plugin-related endpoints by removing synchronous file reads and leveraging an in-memory configuration cache. The configuration is now explicitly reloaded only after modification, such as during plugin installation or uninstallation. The changes are logical and effectively address the performance concern of blocking I/O on hot API paths. I've identified a minor code duplication for the configuration reloading logic, which could be refactored to improve maintainability.

Comment on lines +3162 to +3169
// Reload config to sync state
try {
state.config = loadMilaidyConfig();
} catch (err) {
logger.warn(
`[milaidy-api] Failed to reload config after install: ${err}`,
);
}

Choose a reason for hiding this comment

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

medium

This logic to reload the configuration is duplicated in the uninstall handler as well (lines 3232-3239). To improve maintainability and reduce code duplication, consider extracting this into a helper function.

For example, you could define a function like this at the module level:

function reloadConfigState(state: ServerState, action: 'install' | 'uninstall'): void {
  try {
    state.config = loadMilaidyConfig();
  } catch (err) {
    logger.warn(
      `[milaidy-api] Failed to reload config after ${action}: ${err instanceof Error ? err.message : String(err)}`,
    );
  }
}

Then you could call reloadConfigState(state, 'install') here and reloadConfigState(state, 'uninstall') in the other handler. This also makes the error logging safer.

Comment on lines +3232 to +3239
// Reload config to sync state
try {
state.config = loadMilaidyConfig();
} catch (err) {
logger.warn(
`[milaidy-api] Failed to reload config after uninstall: ${err}`,
);
}

Choose a reason for hiding this comment

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

medium

This is a duplication of the config reload logic from the install handler (lines 3162-3169). As mentioned in the other comment, extracting this to a shared helper function would be a good improvement for maintainability.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant