Start starts the HTTP server. It blocks until ctx is cancelled.
(ctx context.Context)
| 73 | |
| 74 | // Start starts the HTTP server. It blocks until ctx is cancelled. |
| 75 | func (s *Server) Start(ctx context.Context) error { |
| 76 | mux := http.NewServeMux() |
| 77 | s.registerRoutes(mux) |
| 78 | s.mountStatic(mux) |
| 79 | |
| 80 | var handler http.Handler = mux |
| 81 | handler = projectMiddleware(s.resolver, handler) |
| 82 | if s.config.Dev { |
| 83 | handler = corsMiddleware(handler) |
| 84 | } |
| 85 | |
| 86 | srv := &http.Server{ |
| 87 | Addr: fmt.Sprintf(":%d", s.config.Port), |
| 88 | Handler: handler, |
| 89 | } |
| 90 | |
| 91 | // Start file watcher in background |
| 92 | go func() { |
| 93 | if err := s.watcher.Start(); err != nil && s.config.Verbose { |
| 94 | fmt.Printf("watcher error: %v\n", err) |
| 95 | } |
| 96 | }() |
| 97 | |
| 98 | // Graceful shutdown |
| 99 | go func() { |
| 100 | <-ctx.Done() |
| 101 | s.watcher.Stop() |
| 102 | shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| 103 | defer cancel() |
| 104 | srv.Shutdown(shutdownCtx) |
| 105 | }() |
| 106 | |
| 107 | listener, err := net.Listen("tcp", srv.Addr) |
| 108 | if err != nil { |
| 109 | return fmt.Errorf("failed to listen on port %d: %w", s.config.Port, err) |
| 110 | } |
| 111 | |
| 112 | s.printBanner() |
| 113 | |
| 114 | if err := srv.Serve(listener); err != http.ErrServerClosed { |
| 115 | return err |
| 116 | } |
| 117 | return nil |
| 118 | } |
| 119 | |
| 120 | func (s *Server) registerRoutes(mux *http.ServeMux) { |
| 121 | mux.HandleFunc("GET /api/projects", handleProjects(s.config.ListProjects)) |
no test coverage detected