Skip to content

session.wait() seems to be not effective #265

@followheart26

Description

@followheart26

Describe the bug
The server is deployed by k8s with rolling updates. Although the same domain name is used, the actual IP address changes each time it is deployed. This causes the client's long connection to fail during the release because the original target IP address has become invalid. It is hoped that the client's session.wait can sense the server's close and then re-establish the session.
However,the session.wait function seems to be not effective. When the sever invoke session.close. the client session.wait never end or it will report error fatal error: all goroutines are asleep - deadlock!

To Reproduce

server:
httpServer.RegisterOnShutdown(func() {
		o.log.Info("begin close ssession")
		// each session
		for session := range o.svr.Sessions() {
			o.log.Info("close session:sessionId: %s", session.ID())
			session.Close()
		}
	})

	//o.log.Info("mcp %s server receive signal: %s", o.Transport, sig.String())

	stime := time.Now()

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

	time.Sleep(time.Second * 10)

	if err := httpServer.Shutdown(ctx); err != nil && !errors.Is(err, http.ErrServerClosed) {
		return err
	} else {
		o.log.Info("mcp %s server gracefully stopped, consume times %s", o.Transport, time.Since(stime))
	}

client:

var transport mcp.Transport
	transport = mcp.NewStreamableClientTransport("http://127.0.0.1:9703/mcp", nil)

	ctx := context.Background()
	client := mcp.NewClient(&mcp.Implementation{Name: "mcp-client", Version: "v1.0.0"}, nil)
	cs, err := client.Connect(ctx, transport)
	if err != nil {
		log.Fatal(err)
	}
	defer cs.Close()

	printSection("tools", cs.Tools(ctx, nil), func(t *mcp.Tool) string { return t.Name })
	printSection("resources", cs.Resources(ctx, nil), func(r *mcp.Resource) string { return r.Name })
	printSection("resource templates", cs.ResourceTemplates(ctx, nil), func(r *mcp.ResourceTemplate) string { return r.Name })
	printSection("prompts", cs.Prompts(ctx, nil), func(p *mcp.Prompt) string { return p.Name })
	//go func() {
	//	for {
	//		time.Sleep(time.Second)
	//		println("client healty:%s", cs.ID())
	//	}
	//}()
	println("begin wait")
	err = cs.Wait()

	print("end")
	if err != nil {
		println("error!!!!!")
	}

Expected behavior
wait() can end when the session close, so i can rebuild the session and it will not be known by user and not report broken session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds investigationstatus unclear, requires more work and discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions