| 421 | } |
| 422 | |
| 423 | func (s *Server) Run(ctx context.Context) error { |
| 424 | g, ctx := errgroup.WithContext(ctx) |
| 425 | s.backgroundCtx = ctx |
| 426 | g.Go(func() error { return s.dispatchLoop(ctx) }) |
| 427 | g.Go(func() error { return s.writeLoop(ctx) }) |
| 428 | |
| 429 | // Don't run readLoop in the group, as it blocks on stdin read and cannot be cancelled. |
| 430 | readLoopErr := make(chan error, 1) |
| 431 | g.Go(func() error { |
| 432 | select { |
| 433 | case <-ctx.Done(): |
| 434 | return ctx.Err() |
| 435 | case err := <-readLoopErr: |
| 436 | return err |
| 437 | } |
| 438 | }) |
| 439 | go func() { readLoopErr <- s.readLoop(ctx) }() |
| 440 | |
| 441 | if err := g.Wait(); err != nil && !errors.Is(err, io.EOF) && ctx.Err() != nil { |
| 442 | return err |
| 443 | } |
| 444 | return nil |
| 445 | } |
| 446 | |
| 447 | func (s *Server) readLoop(ctx context.Context) error { |
| 448 | for { |