mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-11 16:53:43 +08:00
- Removed `examples/plugin/main.go` and `internal/pluginhost/loader_plugin.go` after migrating to a more modular system. - Introduced `streamBridge` in `internal/pluginhost/stream_bridge.go` for efficient stream handling and communication. - Added examples of `thinking` plugins written in both Rust and Go under `examples/plugin/thinking`. - Enhanced test coverage for plugin host system changes, including stream chunk translation and thinking logic. - Improved API compatibility and ensured backward-compatible upgrades for plugin execution.
80 lines
1.3 KiB
Go
80 lines
1.3 KiB
Go
package pluginhost
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
type guardedPluginClient struct {
|
|
mu sync.Mutex
|
|
cond *sync.Cond
|
|
inner pluginClient
|
|
calls int
|
|
closed bool
|
|
}
|
|
|
|
func newGuardedPluginClient(inner pluginClient) pluginClient {
|
|
client := &guardedPluginClient{inner: inner}
|
|
client.cond = sync.NewCond(&client.mu)
|
|
return client
|
|
}
|
|
|
|
func (c *guardedPluginClient) Call(ctx context.Context, method string, request []byte) ([]byte, error) {
|
|
inner, errAcquire := c.acquire()
|
|
if errAcquire != nil {
|
|
return nil, errAcquire
|
|
}
|
|
defer c.release()
|
|
return inner.Call(ctx, method, request)
|
|
}
|
|
|
|
func (c *guardedPluginClient) acquire() (pluginClient, error) {
|
|
if c == nil {
|
|
return nil, fmt.Errorf("plugin client is closed")
|
|
}
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
if c.closed || c.inner == nil {
|
|
return nil, fmt.Errorf("plugin client is closed")
|
|
}
|
|
c.calls++
|
|
return c.inner, nil
|
|
}
|
|
|
|
func (c *guardedPluginClient) release() {
|
|
c.mu.Lock()
|
|
c.calls--
|
|
if c.calls == 0 {
|
|
c.cond.Broadcast()
|
|
}
|
|
c.mu.Unlock()
|
|
}
|
|
|
|
func (c *guardedPluginClient) Shutdown() {
|
|
if c == nil {
|
|
return
|
|
}
|
|
|
|
var inner pluginClient
|
|
c.mu.Lock()
|
|
if c.closed {
|
|
for c.calls > 0 {
|
|
c.cond.Wait()
|
|
}
|
|
c.mu.Unlock()
|
|
return
|
|
}
|
|
c.closed = true
|
|
for c.calls > 0 {
|
|
c.cond.Wait()
|
|
}
|
|
inner = c.inner
|
|
c.inner = nil
|
|
c.mu.Unlock()
|
|
|
|
if inner != nil {
|
|
inner.Shutdown()
|
|
}
|
|
}
|