{"record":{"id":"dad6a507a88d6d8f","repo":"yudai/gotty","slug":"server-is-shutting-down","errorCode":null,"errorMessage":"Server is shutting down","messagePattern":"Server is shutting down","errorType":"http","errorClass":null,"httpStatus":503,"severity":"error","filePath":"server/handlers.go","lineNumber":34,"sourceCode":"\t\"github.com/yudai/gotty/webtty\"\n)\n\nfunc (server *Server) generateHandleWS(ctx context.Context, cancel context.CancelFunc, counter *counter) http.HandlerFunc {\n\tonce := new(int64)\n\n\tgo func() {\n\t\tselect {\n\t\tcase <-counter.timer().C:\n\t\t\tcancel()\n\t\tcase <-ctx.Done():\n\t\t}\n\t}()\n\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tif server.options.Once {\n\t\t\tsuccess := atomic.CompareAndSwapInt64(once, 0, 1)\n\t\t\tif !success {\n\t\t\t\thttp.Error(w, \"Server is shutting down\", http.StatusServiceUnavailable)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tnum := counter.add(1)\n\t\tcloseReason := \"unknown reason\"\n\n\t\tdefer func() {\n\t\t\tnum := counter.done()\n\t\t\tlog.Printf(\n\t\t\t\t\"Connection closed by %s: %s, connections: %d/%d\",\n\t\t\t\tcloseReason, r.RemoteAddr, num, server.options.MaxConnection,\n\t\t\t)\n\n\t\t\tif server.options.Once {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}()","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/yudai/gotty/blob/a080c85cbc59226c94c6941ad8c395232d72d517/server/handlers.go#L16-L52","documentation":"Not a thrown exception but the HTTP body of a 503 (StatusServiceUnavailable) response: in --once mode the single allowed connection has already been claimed via a CAS on the once counter, so every subsequent websocket request is refused with this plain-text message while the server winds down.","triggerScenarios":"Thrown at server/handlers.go:34 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Expected behavior in once mode: have clients honor 503 and stop retrying","Restart or supervise the server (systemd) to re-arm one-shot sessions","Use a load balancer to drain traffic once the one-shot slot is taken"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a080c85cbc59226c94c6941ad8c395232d72d517","analyzedAt":"2026-09-02T16:42:38.150Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}