Skip to content

Conversation

@fatelei
Copy link
Contributor

@fatelei fatelei commented Jan 28, 2026

fix #588 #590 langgenius/dify#31684

Problem

Remote debugging plugins were not being synchronized across cluster nodes, causing "no plugin available nodes found" errors when trying to invoke plugins from different nodes.

Root Causes

  1. Remote debugging plugins not registered to cluster - The ClusterTunnel notifier was not being added to ControlPanel
  2. Plugin ID inconsistency - Remote plugins used different plugin_id formats during installation vs. querying
  3. Non-idempotent registration - RegisterPlugin failed on reconnection with "plugin has been registered" error

Changes

Core Fixes

  • internal/types/models/curd/atomic.go:

    • Unify plugin_id calculation for remote plugins (author/name without version)
    • Remove plugin_id from plugin query conditions
    • Clear old cache when plugin_id is updated
  • internal/cluster/plugin.go:

    • Make RegisterPlugin idempotent by updating existing plugin instead of returning error
  • internal/core/control_panel/daemon.go:

    • Add cluster field to ControlPanel
    • Add SetCluster() method for lazy cluster initialization
  • internal/core/control_panel/server_debugger.go:

    • Register remote debugging plugins to cluster on connection
    • Unregister from cluster on disconnection
  • internal/core/plugin_manager/manager.go:

    • Add SetCluster() method to set cluster after initialization
  • internal/server/server.go:

    • Call SetCluster() instead of AddClusterTunnel()

Design Decision

Only remote debugging plugins are synchronized across cluster nodes. Local plugins run only on the node where they are installed and are not registered to the cluster.

Additional Improvements

  • Error handling improvements using errors.Is() instead of ==
  • Handle 404 for missing plugin assets gracefully
  • Handle already-installed debugging plugins gracefully

Testing

  • Remote debugging plugin can be invoked from any node in the cluster
  • Plugin reconnection works without errors
  • Cache invalidation works correctly when plugin_id changes

Description

Please provide a brief description of the changes made in this pull request.
Please also include the issue number if this is related to an issue using the format Fixes #123 or Closes #123.

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Performance improvement
  • Other

Essential Checklist

Testing

  • I have tested the changes locally and confirmed they work as expected
  • I have added unit tests where necessary and they pass successfully

Bug Fix (if applicable)

  • I have used GitHub syntax to close the related issue (e.g., Fixes #123 or Closes #123)

Additional Information

Please provide any additional context that would help reviewers understand the changes.

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 28, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @fatelei, 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 addresses critical issues related to the synchronization and management of remote debugging plugins within a cluster environment. Previously, these plugins were not reliably registered or discoverable across different nodes, leading to invocation failures. The changes ensure that remote debugging plugins are correctly registered, their IDs are consistently managed, and their lifecycle events (connection/disconnection) are propagated across the cluster, significantly improving the stability and functionality of distributed debugging.

Highlights

  • Cluster Synchronization for Remote Debugging Plugins: Remote debugging plugins are now properly registered and synchronized across cluster nodes, resolving "no plugin available nodes found" errors by ensuring the ClusterTunnel notifier is correctly integrated and plugin lifecycle events are handled.
  • Idempotent Plugin Registration: The RegisterPlugin function has been made idempotent. If a plugin is already registered, subsequent registration attempts will update its state rather than returning an error, improving resilience during reconnections.
  • Unified Plugin ID Calculation: Plugin ID calculation for remote plugins now consistently uses the "author/name" format (without version) during both installation and querying, addressing previous inconsistencies that led to incorrect plugin identification.
  • Improved Error Handling: Error comparisons throughout the codebase have been updated to use errors.Is() instead of direct equality checks, leading to more robust and idiomatic Go error handling.
  • Graceful Plugin Management: The system now gracefully handles scenarios such as missing plugin assets (returning 404s appropriately) and re-installation of already-installed debugging plugins, preventing unnecessary errors.

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

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.

@dosubot dosubot bot added bug Something isn't working enhancement New feature or request go Pull requests that update go code labels Jan 28, 2026
Copy link
Contributor

@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 effectively addresses issues with remote debugging plugin synchronization across cluster nodes by making registration idempotent, unifying plugin ID formats, and ensuring plugins are correctly registered with the cluster. However, a high-severity cache key injection vulnerability was identified in the cache key generation logic, which could allow an attacker to poison the cache and potentially access or manipulate plugin installations belonging to other tenants. It is recommended to sanitize inputs used in cache keys or use a more secure serialization format. Additionally, my review includes suggestions to improve error handling, prevent potential race conditions, enhance test stability by avoiding fixed sleeps, and refactor duplicated code for better maintainability. A bug where a 'not found' error incorrectly results in a 200 OK response was also found and a fix provided.

@Stream29 Stream29 self-requested a review January 28, 2026 14:57
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jan 29, 2026
Remote debugging plugins were not being synchronized across cluster nodes,
causing "no plugin available nodes found" errors when trying to invoke
plugins from different nodes.

1. **Remote debugging plugins not registered to cluster** - The
   `ClusterTunnel` notifier was not being added to ControlPanel
2. **Plugin ID inconsistency** - Remote plugins used different plugin_id
   formats during installation vs. querying
3. **Non-idempotent registration** - `RegisterPlugin` failed on reconnection
   with "plugin has been registered" error

- **internal/types/models/curd/atomic.go**:
  - Unify plugin_id calculation for remote plugins (author/name without version)
  - Remove plugin_id from plugin query conditions
  - Clear old cache when plugin_id is updated

- **internal/cluster/plugin.go**:
  - Make `RegisterPlugin` idempotent by updating existing plugin instead
    of returning error

- **internal/core/control_panel/daemon.go**:
  - Add cluster field to ControlPanel
  - Add SetCluster() method for lazy cluster initialization

- **internal/core/control_panel/server_debugger.go**:
  - Register remote debugging plugins to cluster on connection
  - Unregister from cluster on disconnection

- **internal/core/plugin_manager/manager.go**:
  - Add SetCluster() method to set cluster after initialization

- **internal/server/server.go**:
  - Call SetCluster() instead of AddClusterTunnel()

Only remote debugging plugins are synchronized across cluster nodes.
Local plugins run only on the node where they are installed and are
not registered to the cluster.

- Error handling improvements using `errors.Is()` instead of `==`
- Handle 404 for missing plugin assets gracefully
- Handle already-installed debugging plugins gracefully

- Remote debugging plugin can be invoked from any node in the cluster
- Plugin reconnection works without errors
- Cache invalidation works correctly when plugin_id changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request go Pull requests that update go code size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

remote debug return no node available

2 participants