8000 The SSEServer.Shutdown() function deadlocks, preventing the service from shutting down. · Issue #263 · mark3labs/mcp-go · GitHub
[go: up one dir, main page]

Skip to content
The SSEServer.Shutdown() function deadlocks, preventing the service from shutting down. #263
@yorkershi

Description

@yorkershi

s.mu.Lock()

func (s *SSEServer) Start(addr string) error {
	s.mu.Lock() 
	defer s.mu.Unlock()

	if s.srv == nil {
		s.srv = &http.Server{
			Addr:    addr,
			Handler: s,
		}
	} else {
		if s.srv.Addr == "" {
			s.srv.Addr = addr
		} else if s.srv.Addr != addr {
			return fmt.Errorf("conflicting listen address: WithHTTPServer(%q) vs Start(%q)", s.srv.Addr, addr)
		}
	}

	return s.srv.ListenAndServe()
}

note: After the SSE service starts, the Start() function will be blocked until the service ends.

s.mu.RLock()

func (s *SSEServer) Shutdown(ctx context.Context) error {
	s.mu.RLock()  **ISSUE: When the service shuts down, it will be permanently blocked at the statement s.mu.RLock(), causing the service to fail to shut down properly because the Start() function has not ended.**
	srv := s.srv
	s.mu.RUnlock()

	if srv != nil {
		s.sessions.Range(func(key, value interface{}) bool {
			if session, ok := value.(*sseSession); ok {
				close(session.done)
			}
			s.sessions.Delete(key)
			return true
		})

		return srv.Shutdown(ctx)
	}
	return nil
}

test case

func StartSSEServer() error {
	stopChan := make(chan os.Signal, 1)
	signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)
	sseServer := server.NewSSEServer(...)

	go func() {
		if err := sseServer.Start(...); err != nil && !errors.Is(err, http.ErrServerClosed) {
			fmt.Printf("SSEServer failed to start: %s\n", err.Error())
                         return
		}
	}()

	sig := <-stopChan

	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	if err := sseServer.Shutdown(ctx); err != nil && !errors.Is(err, http.ErrServerClosed) {
		return err
	}
	return nil
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0