Bluemage/go/cmd/bluemage/serve/serve.go

64 lines
1.5 KiB
Go

package serve
import (
"context"
"errors"
"log/slog"
"net/http"
"time"
"connectrpc.com/connect"
"github.com/spf13/cobra"
"github.com/stephenafamo/bob"
"github.com/tigorlazuardi/bluemage/go/api"
"github.com/tigorlazuardi/bluemage/go/gen/proto/device/v1/v1connect"
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
"github.com/tigorlazuardi/bluemage/go/server"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
var Cmd = &cobra.Command{
Use: "serve",
RunE: func(cmd *cobra.Command, args []string) error {
db, err := bob.Open("sqlite3", "file:go/data.db")
if err != nil {
return errs.Wrap(err, "failed to open database")
}
api := &api.API{
DB: db,
}
handler := &server.Server{
DeviceHandler: server.DeviceHandler{
API: api,
},
}
mux := http.NewServeMux()
mux.Handle(v1connect.NewDeviceServiceHandler(handler, connect.WithInterceptors(server.LogInterceptor())))
server := &http.Server{
Addr: ":8080",
Handler: h2c.NewHandler(server.WithCORS(mux), &http2.Server{}),
}
go func() {
<-cmd.Context().Done()
slog.Info("Exit signal received. Shutting down server")
shutdownCtx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
_ = server.Shutdown(shutdownCtx)
}()
slog.Info("ConnectRPC server started", "addr", server.Addr)
err = server.ListenAndServe()
if err != nil && !errors.Is(err, http.ErrServerClosed) {
return errs.Wrap(err, "failed to serve")
}
return errors.Join(db.Close())
},
SilenceUsage: true,
}