Line-Protocol TCP Server (Go)
Topics: TCP, line protocol, concurrency, graceful drain
Problem
Build a small scheme simulator: a TCP server speaking a newline-terminated request/response
protocol, with a graceful shutdown that drains in-flight work. (Inspired by the kind of payment-scheme
simulators payment platforms build for testing — the protocol here is a generic task runner.)
func New(addr string, grace time.Duration) *Server
func (s *Server) Start(ctx context.Context) error
func (s *Server) Addr() string
func (s *Server) Started() <-chan struct{}
Protocol (one request in flight per connection, connections reused):
RUN|<ms>\n → after ~<ms> of simulated work, OK|done\n.
- Malformed (not
RUN|<int>) → ERR|invalid request\n.
<ms> not a non-negative integer → ERR|invalid amount\n.
Graceful shutdown (on ctx cancel):
- Stop accepting new connections.
- Give in-flight requests up to
grace to finish.
- A request still running when
grace expires → ERR|cancelled\n.
Start returns nil once in-flight work has drained.
Key concepts
- Per-connection goroutine reading newline-framed requests with
bufio.Reader; one request is
answered before the next is read.
- Drain accounting: track the number of in-process requests; on shutdown,
sync.Cond waits
for that count to hit zero, and a time.AfterFunc(grace) flips a hard flag that makes
long-running work bail out with cancelled.
- Scope: slow/half-open clients are out of scope — only clean termination by client or server.
The struct, New, Addr, Started, and parse are provided; you implement Start and the
connection handling.
Run
go test -v -race ./challenges/line-protocol-server/go/
Sign in to submit your solution.