diff --git a/cmd/server/main.go b/cmd/server/main.go index cf47c23..2ba4c19 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -49,6 +49,7 @@ func main() { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c + app.L.Info("shutting down") cancel() }() diff --git a/core/server.go b/core/server.go index 71f22e2..1723ad3 100644 --- a/core/server.go +++ b/core/server.go @@ -1,13 +1,10 @@ package core import ( - "bufio" "context" - "fmt" "log/slog" "net" - - "github.com/google/uuid" + "time" ) type Server struct { @@ -21,11 +18,17 @@ type Server struct { func NewServer(ctx context.Context, l *slog.Logger, port string) *Server { var s Server - // TODO: Check for context cancellation and cleanup - c := make(chan *Session) s.Sessions = c - ln, err := net.Listen("tcp", port) + lc := net.ListenConfig{ + KeepAlive: 5 * time.Minute, + KeepAliveConfig: net.KeepAliveConfig{ + Enable: true, + Idle: 3 * time.Minute, + Interval: 15 * time.Second, + }, + } + ln, err := lc.Listen(ctx, "tcp", port) if err != nil { s.l.With( slog.Any("error", err), @@ -43,70 +46,18 @@ func NewServer(ctx context.Context, l *slog.Logger, port string) *Server { func (s *Server) Start() { s.l.Debug("starting telnet server") - // TODO: Check for context cancellation and cleanup for { - conn, err := s.ln.Accept() - if err != nil { - s.l.With( - slog.Any("error", err), - ).Error("could not accept tcp connection") - } - s.Sessions <- NewSession(s.ctx, conn, Printer{}, s.l) - - } -} - -type Session struct { - c net.Conn - ctx context.Context - p Printer - l *slog.Logger - - userID uint64 -} - -func NewSession(ctx context.Context, c net.Conn, p Printer, l *slog.Logger) *Session { - sid := uuid.New() - return &Session{ - ctx: ctx, - l: l.With(slog.String("sid", sid.String())), - c: c, - } -} - -func (s *Session) bufferInput(commands chan string) { - scanner := bufio.NewScanner(s.c) - defer close(commands) - - for scanner.Scan() { - err := scanner.Err() - switch err { - case nil: - commands <- scanner.Text() - default: - s.l.With(slog.Any("error", scanner.Err())).Error("error scanning input") - return - } - } - - s.l.Debug("session terminated") -} - -func (s *Session) Start() { - s.l.Debug("starting telnet session") - fmt.Fprint(s.c, "Welcome to Bing Bong.\n") - - commands := make(chan string) - go s.bufferInput(commands) - - for command := range commands { - s.l.With(slog.String("command", command)).Debug("command recieved") - _, err := fmt.Fprintf(s.c, "> %q\n", command) - if err != nil { - s.l.With( - slog.Any("error", err), - ).Error("connection closed on write") + select { + case <-s.ctx.Done(): return + default: + conn, err := s.ln.Accept() + if err != nil { + s.l.With( + slog.Any("error", err), + ).Error("could not accept tcp connection") + } + s.Sessions <- NewSession(s.ctx, conn, Printer{}, s.l) } } }