package main import ( "context" "errors" "log" "os" "os/signal" "recipe-manager/config" "recipe-manager/services/oauth" "syscall" "time" "github.com/spf13/viper" ) func main() { config, err := loadConfig(".") if err != nil { // use default config instead log.Fatal(err) } oauthService := oauth.NewOAuthService(config) server := NewServer(config, oauthService) tusServer := NewTusServer(config, oauthService) serverCtx, serverStopCtx := context.WithCancel(context.Background()) tusServerCtx, tusServerStopCtx := context.WithCancel(context.Background()) sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) go func() { <-sig shutdownCtx, cancel := context.WithTimeout(serverCtx, 30*time.Second) tusShutdownCtx, tusShutdownCancel := context.WithTimeout(tusServerCtx, 30*time.Second) go func() { <-shutdownCtx.Done() if errors.Is(shutdownCtx.Err(), context.DeadlineExceeded) { log.Println("Shutdown timeout, force exit") cancel() } }() go func() { <-tusShutdownCtx.Done() if errors.Is(tusShutdownCtx.Err(), context.DeadlineExceeded) { log.Println("Tus server shutdown timeout, force exit") tusShutdownCancel() } }() err := server.Shutdown(shutdownCtx) if err != nil { log.Fatal(err) } err = tusServer.Shutdown(tusShutdownCtx) if err != nil { log.Fatal(err) } tusServerStopCtx() serverStopCtx() }() // Spawn a goroutine to run git pull every 10 minutes //go RunGitRecipeWorker() // ** Use crontab instead ** go func() { err := tusServer.Run() if err != nil { log.Fatal(err) } }() go func() { err := server.Run() if err != nil { log.Fatal(err) } }() <-tusServerCtx.Done() <-serverCtx.Done() } func loadConfig(path string) (*config.ServerConfig, error) { viper.AddConfigPath(path) viper.SetConfigName("app") viper.SetConfigType("env") viper.AutomaticEnv() var serverConfig config.ServerConfig err := viper.ReadInConfig() if err != nil { return nil, err } err = viper.Unmarshal(&serverConfig) if err != nil { return nil, err } return &serverConfig, nil }