{"record":{"id":"e4ee8d4d27318956","repo":"geektutu/7days-golang","slug":"connection-is-shut-down-e4ee8d","errorCode":null,"errorMessage":"connection is shut down","messagePattern":"connection is shut down","errorType":"exception","errorClass":"ErrShutdown","httpStatus":null,"severity":"error","filePath":"gee-rpc/day3-service/client.go","lineNumber":50,"sourceCode":"// Client represents an RPC Client.\n// There may be multiple outstanding Calls associated\n// with a single Client, and a Client may be used by\n// multiple goroutines simultaneously.\ntype Client struct {\n\tcc       codec.Codec\n\topt      *Option\n\tsending  sync.Mutex // protect following\n\theader   codec.Header\n\tmu       sync.Mutex // protect following\n\tseq      uint64\n\tpending  map[uint64]*Call\n\tclosing  bool // user has called Close\n\tshutdown bool // server has told us to stop\n}\n\nvar _ io.Closer = (*Client)(nil)\n\nvar ErrShutdown = errors.New(\"connection is shut down\")\n\n// Close the connection\nfunc (client *Client) Close() error {\n\tclient.mu.Lock()\n\tdefer client.mu.Unlock()\n\tif client.closing {\n\t\treturn ErrShutdown\n\t}\n\tclient.closing = true\n\treturn client.cc.Close()\n}\n\n// IsAvailable return true if the client does work\nfunc (client *Client) IsAvailable() bool {\n\tclient.mu.Lock()\n\tdefer client.mu.Unlock()\n\treturn !client.shutdown && !client.closing\n}","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day3-service/client.go#L32-L68","documentation":"Sentinel error ErrShutdown (io.Closer semantics) indicating the client connection is no longer usable: either the user called Close (closing=true) or the server told the client to stop (shutdown=true). Returned by Close when already closing and used to fail pending calls.","triggerScenarios":"Thrown at gee-rpc/day3-service/client.go:50 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Do not use the Client after calling Close; create a new one via Dial.","Check for errors.Is(err, ErrShutdown) and reconnect with a fresh client.","For graceful restarts, drain outstanding Call.Done channels before closing the client."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}