fix(local-runtime): recover stopped plugin instances - #766
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces robust error recovery and instance eviction mechanisms for local plugin runtimes. It implements write retry logic with a budget in GenericInvokePlugin, adds state tracking (stopped flag) and thread-safe writes to PluginInstance, and updates the scheduling loop to prune stopped instances and immediately trigger rescheduling via a new scheduleKick channel. Additionally, it updates load balancing to skip stopped instances and adds unit tests for these recovery behaviors. The reviewer suggested adding a defensive nil check for s.inWriter in Write to prevent potential nil pointer dereferences during testing or partial initialization.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Description
Fixes #765
This pull request fixes a local runtime recovery issue where plugin-daemon can continue routing requests to a local plugin instance after that instance's stdio pipes have already been closed.
When this happens, dispatch fails before the request reaches the plugin process, for example:
The root cause is that stopped local plugin instances are removed from the runtime instance pool asynchronously. During that gap, the load balancer can still select the stale instance, and the write path can still attempt to write to its closed stdin pipe.
This PR makes the local runtime recover from that state by:
PluginInstanceas stopped synchronously when stdio is closed or stdout exitsType of Change
Essential Checklist
Testing
Bug Fix (if applicable)
Fixes #123orCloses #123)Additional Information
Local validation:
go test ./internal/core/local_runtime/... ./internal/core/io_tunnel/...go build ./cmd/serverThe change is limited to local plugin runtime instance lifecycle, load balancing, stdin write handling, and write-before-dispatch retry behavior. It does not change serverless runtime behavior.