Skip to content

Fix GetPlugin: deadlock, wrong filepath, and missing lazy load#1

Merged
git88997 merged 4 commits intomainfrom
copilot/fix-plugins-bug
Feb 22, 2026
Merged

Fix GetPlugin: deadlock, wrong filepath, and missing lazy load#1
git88997 merged 4 commits intomainfrom
copilot/fix-plugins-bug

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 22, 2026

GetPlugin() had three bugs: a deadlock from holding a read lock while acquiring a write lock, incorrect plugin file path construction, and no lazy loading when the module key was absent from the map.

  • Deadlock: defer pm.mu.RUnlock() kept the read lock held when pm.RegisterPlugin() attempted pm.mu.Lock(). Replaced with manual lock management, releasing before the write path.
  • Wrong filepath: filepath.Join(global.PluginDir, module, id, ".go") produces dir/module/id/.go. Fixed to filepath.Join(global.PluginDir, module, fmt.Sprintf("%v.go", id)).
  • Missing lazy load: Lazy loading was nested inside if modPlugins, ok := pm.plugins[module]; ok, so unknown modules returned nil, false immediately. Moved lazy loading outside the module existence check.
// Before (deadlocks + wrong path + no fallback for unknown modules)
func (pm *PluginManager) GetPlugin(module, id string) (interfaces.Plugin, bool) {
    pm.mu.RLock()
    defer pm.mu.RUnlock()
    if modPlugins, ok := pm.plugins[module]; ok {
        // ...
        pm.RegisterPlugin(module, id, plg) // write lock while read lock held → deadlock
    }
    return nil, false
}

// After
func (pm *PluginManager) GetPlugin(module, id string) (interfaces.Plugin, bool) {
    pm.mu.RLock()
    if modPlugins, ok := pm.plugins[module]; ok {
        if plugin, ok := modPlugins[id]; ok {
            cloned := plugin.Clone()
            pm.mu.RUnlock()
            return cloned, true
        }
    }
    pm.mu.RUnlock()
    // lazy load without holding any lock
    plg, err := LoadCustomPlugin(filepath.Join(global.PluginDir, module, fmt.Sprintf("%v.go", id)), module, id)
    // ...
}

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 3 commits February 22, 2026 17:03
…known modules

Three bugs fixed in GetPlugin():
1. Deadlock: defer RUnlock() kept read lock held when RegisterPlugin()
   tried to acquire write lock. Fix: manual RLock/RUnlock management.
2. Wrong filepath: filepath.Join(dir, module, id, ".go") produced
   "dir/module/id/.go" instead of "dir/module/id.go". Fix: use
   fmt.Sprintf("%v.go", id).
3. Missing lazy load: when module key didn't exist in the plugins map,
   lazy loading was never attempted. Fix: move lazy loading outside
   the module existence check.

Co-authored-by: git88997 <247747451+git88997@users.noreply.github.com>
…known modules

Co-authored-by: git88997 <247747451+git88997@users.noreply.github.com>
Co-authored-by: git88997 <247747451+git88997@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix bug in plugins functionality Fix GetPlugin: deadlock, wrong filepath, and missing lazy load Feb 22, 2026
Copilot AI requested a review from git88997 February 22, 2026 17:09
Copy link
Copy Markdown
Owner

@git88997 git88997 left a comment

Choose a reason for hiding this comment

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

fix

@git88997 git88997 marked this pull request as ready for review February 22, 2026 17:12
@git88997 git88997 merged commit 6409743 into main Feb 22, 2026
@git88997 git88997 deleted the copilot/fix-plugins-bug branch February 22, 2026 17:13
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.

2 participants