Files
iqudo-top1/codes/main.go
2026-08-06 21:48:42 +08:00

82 lines
2.3 KiB
Go

package main
import (
"context"
"embed"
"flag"
"fmt"
"io/fs"
"net/http"
"os"
"os/signal"
"syscall"
"git.iwork-ai.com/xdc/iqudo-top1/internal/auth"
"git.iwork-ai.com/xdc/iqudo-top1/internal/config"
"git.iwork-ai.com/xdc/iqudo-top1/internal/database"
"git.iwork-ai.com/xdc/iqudo-top1/internal/httpserver"
"git.iwork-ai.com/xdc/iqudo-top1/internal/logger"
"git.iwork-ai.com/xdc/iqudo-top1/internal/migration"
"go.uber.org/zap"
)
//go:embed migrations/*.sql
var migrationFiles embed.FS
//go:embed web/dist/*
var frontendFiles embed.FS
func main() {
environment := flag.String("env", "", "runtime environment: development, test, prod")
configDir := flag.String("config-dir", "configs", "configuration directory")
flag.Parse()
cfg, err := config.Load(config.LoadOptions{Environment: *environment, ConfigDir: *configDir})
if err != nil {
fmt.Fprintf(os.Stderr, "load configuration: %v\n", err)
os.Exit(1)
}
log, err := logger.New(cfg.App.Env, cfg.App.Name)
if err != nil {
fmt.Fprintf(os.Stderr, "create logger: %v\n", err)
os.Exit(1)
}
defer log.Sync()
db, err := database.Open(cfg.Database, log)
if err != nil {
log.Fatal("connect database", zap.Error(err))
}
if err := migration.Run(db, migrationFiles); err != nil {
log.Fatal("run database migrations", zap.Error(err))
}
if err := auth.Seed(db, cfg.Seed); err != nil {
log.Fatal("seed administrator", zap.Error(err))
}
frontend, err := fs.Sub(frontendFiles, "web/dist")
if err != nil {
log.Fatal("load embedded frontend", zap.Error(err))
}
authService := auth.NewService(db, cfg.Auth)
handler := httpserver.New(db, authService, frontend, log, cfg.App.Env)
server := &http.Server{Addr: cfg.Server.Address(), Handler: handler, ReadTimeout: cfg.Server.ReadTimeout, WriteTimeout: cfg.Server.WriteTimeout}
go func() {
log.Info("server started", zap.String("address", cfg.Server.Address()))
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal("server stopped unexpectedly", zap.Error(err))
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
<-stop
ctx, cancel := context.WithTimeout(context.Background(), cfg.Server.ShutdownTimeout)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Error("graceful shutdown failed", zap.Error(err))
}
log.Info("server stopped")
}