tss-rocks/backend/cmd/server.go

89 lines
2 KiB
Go

package cmd
import (
"context"
"os"
"os/signal"
"syscall"
"time"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"tss-rocks-be/internal/config"
"tss-rocks-be/internal/server"
"tss-rocks-be/pkg/logger"
)
func GetServerCmd() *cobra.Command {
var configPath string
cmd := &cobra.Command{
Use: "server",
Short: "Start the server",
Long: `Start the server with the specified configuration.`,
RunE: func(cmd *cobra.Command, args []string) error {
// Load configuration
cfg, err := config.Load(configPath)
if err != nil {
return err
}
// Setup logger
logger.Setup(cfg)
// Create a context that can be cancelled
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Set up signal handling
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// Create ent client
client := server.NewEntClient(cfg)
if client == nil {
log.Fatal().Msg("Failed to create database client")
}
defer client.Close()
// Run the auto migration tool
if err := client.Schema.Create(ctx); err != nil {
log.Fatal().Err(err).Msg("Failed to create schema resources")
}
// Create and start server
srv, err := server.New(cfg, client)
if err != nil {
log.Fatal().Err(err).Msg("Failed to create server")
}
// Start server in a goroutine
go func() {
if err := srv.Start(); err != nil {
log.Fatal().Err(err).Msg("Failed to start server")
}
}()
// Wait for interrupt signal
sig := <-sigChan
log.Info().Msgf("Received signal: %v", sig)
// Attempt graceful shutdown with timeout
log.Info().Msg("Shutting down server...")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
log.Error().Err(err).Msg("Server forced to shutdown")
os.Exit(1)
}
return nil
},
}
// Add flags
cmd.Flags().StringVarP(&configPath, "config", "c", "config/config.yaml", "path to config file")
return cmd
}