|
@@ -3,6 +3,7 @@ package remote_manager
|
|
|
import (
|
|
|
"bytes"
|
|
|
"sync"
|
|
|
+ "sync/atomic"
|
|
|
"time"
|
|
|
|
|
|
"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager/basic_manager"
|
|
@@ -26,9 +27,13 @@ type RemotePluginRuntime struct {
|
|
|
// response entity to accept new events
|
|
|
response *stream.Stream[[]byte]
|
|
|
|
|
|
- // callbacks for each session
|
|
|
- callbacks map[string][]func([]byte)
|
|
|
- callbacksLock *sync.RWMutex
|
|
|
+ // messageCallbacks for each session
|
|
|
+ messageCallbacks map[string][]func([]byte)
|
|
|
+ messageCallbacksLock *sync.RWMutex
|
|
|
+
|
|
|
+ // sessionMessageCloser for each session
|
|
|
+ sessionMessageClosers map[string][]func()
|
|
|
+ sessionMessageClosersLock *sync.RWMutex
|
|
|
|
|
|
// channel to notify all waiting routines
|
|
|
shutdownChan chan bool
|
|
@@ -74,25 +79,70 @@ type RemotePluginRuntime struct {
|
|
|
waitLaunchedChanOnce sync.Once
|
|
|
}
|
|
|
|
|
|
+// TODO: unify below methods to a standard interface
|
|
|
+
|
|
|
// Listen creates a new listener for the given session_id
|
|
|
// session id is an unique identifier for a request
|
|
|
-func (r *RemotePluginRuntime) addCallback(session_id string, fn func([]byte)) {
|
|
|
- r.callbacksLock.Lock()
|
|
|
- if _, ok := r.callbacks[session_id]; !ok {
|
|
|
- r.callbacks[session_id] = make([]func([]byte), 0)
|
|
|
+func (r *RemotePluginRuntime) addMessageCallbackHandler(session_id string, fn func([]byte)) {
|
|
|
+ r.messageCallbacksLock.Lock()
|
|
|
+ if _, ok := r.messageCallbacks[session_id]; !ok {
|
|
|
+ r.messageCallbacks[session_id] = make([]func([]byte), 0)
|
|
|
+ }
|
|
|
+ r.messageCallbacks[session_id] = append(r.messageCallbacks[session_id], fn)
|
|
|
+ r.messageCallbacksLock.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+// removeMessageCallbackHandler removes the listener for the given session_id
|
|
|
+func (r *RemotePluginRuntime) removeMessageCallbackHandler(session_id string) {
|
|
|
+ r.messageCallbacksLock.Lock()
|
|
|
+ delete(r.messageCallbacks, session_id)
|
|
|
+ r.messageCallbacksLock.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+// addSessionMessageCloser adds a closer for the given session_id
|
|
|
+// once the session is closed or the connection is closed, the closer will be called
|
|
|
+func (r *RemotePluginRuntime) addSessionMessageCloser(session_id string, fn func()) {
|
|
|
+ // do nothing if the session is already closed
|
|
|
+ if atomic.LoadInt32(&r.closed) == 1 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ r.sessionMessageClosersLock.Lock()
|
|
|
+ if _, ok := r.sessionMessageClosers[session_id]; !ok {
|
|
|
+ r.sessionMessageClosers[session_id] = make([]func(), 0)
|
|
|
}
|
|
|
- r.callbacks[session_id] = append(r.callbacks[session_id], fn)
|
|
|
- r.callbacksLock.Unlock()
|
|
|
+ r.sessionMessageClosers[session_id] = append(r.sessionMessageClosers[session_id], fn)
|
|
|
+ r.sessionMessageClosersLock.Unlock()
|
|
|
}
|
|
|
|
|
|
-// removeCallback removes the listener for the given session_id
|
|
|
-func (r *RemotePluginRuntime) removeCallback(session_id string) {
|
|
|
- r.callbacksLock.Lock()
|
|
|
- delete(r.callbacks, session_id)
|
|
|
- r.callbacksLock.Unlock()
|
|
|
+// removeSessionMessageCloser removes the closer for the given session_id
|
|
|
+func (r *RemotePluginRuntime) removeSessionMessageCloser(session_id string) {
|
|
|
+ // do nothing if the session is already closed
|
|
|
+ if atomic.LoadInt32(&r.closed) == 1 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ r.sessionMessageClosersLock.Lock()
|
|
|
+ delete(r.sessionMessageClosers, session_id)
|
|
|
+ r.sessionMessageClosersLock.Unlock()
|
|
|
}
|
|
|
|
|
|
func (r *RemotePluginRuntime) onDisconnected() {
|
|
|
+ // call all session message closers
|
|
|
+ r.sessionMessageClosersLock.RLock()
|
|
|
+ for _, closer := range r.sessionMessageClosers {
|
|
|
+ for _, fn := range closer {
|
|
|
+ fn()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ r.sessionMessageClosersLock.RUnlock()
|
|
|
+
|
|
|
+ // change the alive status
|
|
|
+ r.alive = false
|
|
|
+
|
|
|
+ // change the closed status
|
|
|
+ atomic.StoreInt32(&r.closed, 1)
|
|
|
+
|
|
|
// close shutdown channel to notify all waiting routines
|
|
|
close(r.shutdownChan)
|
|
|
|