From 6c3d4b197a4c3f87a0807b32ebecbb249c0a0533 Mon Sep 17 00:00:00 2001 From: nathfavour <116535483+nathfavour@users.noreply.github.com> Date: Thu, 15 Jan 2026 23:06:07 +0000 Subject: [PATCH] feat: Refactor session event handler management to use unique IDs for reliable removal. --- go/session.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/go/session.go b/go/session.go index b34fe6e..92fb026 100644 --- a/go/session.go +++ b/go/session.go @@ -9,6 +9,11 @@ import ( "github.com/github/copilot-sdk/go/generated" ) +type sessionHandler struct { + id uint64 + fn SessionEventHandler +} + // Session represents a single conversation session with the Copilot CLI. // // A session maintains conversation state, handles events, and manages tool execution. @@ -44,7 +49,8 @@ type Session struct { // SessionID is the unique identifier for this session. SessionID string client *JSONRPCClient - handlers []SessionEventHandler + handlers []sessionHandler + nextHandlerID uint64 handlerMutex sync.RWMutex toolHandlers map[string]ToolHandler toolHandlersM sync.RWMutex @@ -60,7 +66,7 @@ func NewSession(sessionID string, client *JSONRPCClient) *Session { return &Session{ SessionID: sessionID, client: client, - handlers: make([]SessionEventHandler, 0), + handlers: make([]sessionHandler, 0), toolHandlers: make(map[string]ToolHandler), } } @@ -139,7 +145,9 @@ func (s *Session) On(handler SessionEventHandler) func() { s.handlerMutex.Lock() defer s.handlerMutex.Unlock() - s.handlers = append(s.handlers, handler) + id := s.nextHandlerID + s.nextHandlerID++ + s.handlers = append(s.handlers, sessionHandler{id: id, fn: handler}) // Return unsubscribe function return func() { @@ -147,8 +155,7 @@ func (s *Session) On(handler SessionEventHandler) func() { defer s.handlerMutex.Unlock() for i, h := range s.handlers { - // Compare function pointers - if &h == &handler { + if h.id == id { s.handlers = append(s.handlers[:i], s.handlers[i+1:]...) break } @@ -236,8 +243,10 @@ func (s *Session) handlePermissionRequest(requestData map[string]interface{}) (P // are recovered to prevent crashing the event dispatcher. func (s *Session) dispatchEvent(event SessionEvent) { s.handlerMutex.RLock() - handlers := make([]SessionEventHandler, len(s.handlers)) - copy(handlers, s.handlers) + handlers := make([]SessionEventHandler, 0, len(s.handlers)) + for _, h := range s.handlers { + handlers = append(handlers, h.fn) + } s.handlerMutex.RUnlock() for _, handler := range handlers {