-
Notifications
You must be signed in to change notification settings - Fork 138
Description
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.