mirror of
https://github.com/sablierapp/sablier.git
synced 2025-12-21 13:23:03 +01:00
115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package sabliercmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/sablierapp/sablier/internal/api"
|
|
"github.com/sablierapp/sablier/internal/server"
|
|
"github.com/sablierapp/sablier/pkg/config"
|
|
"github.com/sablierapp/sablier/pkg/sablier"
|
|
"github.com/sablierapp/sablier/pkg/store/inmemory"
|
|
"github.com/sablierapp/sablier/pkg/version"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var newStartCommand = func() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "start",
|
|
Short: "Start the Sablier server",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
err := viper.Unmarshal(&conf)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = Start(cmd.Context(), conf)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// Start starts the Sablier server
|
|
func Start(ctx context.Context, conf config.Config) error {
|
|
// Create context that listens for the interrupt signal from the OS.
|
|
ctx, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
|
|
defer stop()
|
|
logger := setupLogger(conf.Logging)
|
|
|
|
logger.Info("running Sablier version " + version.Info())
|
|
|
|
provider, err := setupProvider(ctx, logger, conf.Provider)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot setup provider: %w", err)
|
|
}
|
|
|
|
store := inmemory.NewInMemory()
|
|
err = store.OnExpire(ctx, sablier.OnInstanceExpired(ctx, provider, logger))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s := sablier.New(logger, store, provider)
|
|
s.BlockingRefreshFrequency = conf.Strategy.Blocking.DefaultRefreshFrequency
|
|
|
|
groups, err := provider.InstanceGroups(ctx)
|
|
if err != nil {
|
|
logger.WarnContext(ctx, "initial group scan failed", slog.Any("reason", err))
|
|
} else {
|
|
s.SetGroups(groups)
|
|
}
|
|
|
|
go s.GroupWatch(ctx)
|
|
instanceStopped := make(chan string)
|
|
go provider.NotifyInstanceStopped(ctx, instanceStopped)
|
|
go func() {
|
|
for stopped := range instanceStopped {
|
|
err := s.RemoveInstance(ctx, stopped)
|
|
if err != nil {
|
|
logger.Warn("could not remove instance", slog.Any("error", err))
|
|
}
|
|
}
|
|
}()
|
|
|
|
if conf.Provider.AutoStopOnStartup {
|
|
err := s.StopAllUnregisteredInstances(ctx)
|
|
if err != nil {
|
|
logger.ErrorContext(ctx, "unable to stop unregistered instances", slog.Any("reason", err))
|
|
}
|
|
}
|
|
|
|
t, err := setupTheme(ctx, conf, logger)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot setup theme: %w", err)
|
|
}
|
|
|
|
strategy := &api.ServeStrategy{
|
|
Theme: t,
|
|
Sablier: s,
|
|
StrategyConfig: conf.Strategy,
|
|
SessionsConfig: conf.Sessions,
|
|
}
|
|
|
|
go server.Start(ctx, logger, conf.Server, strategy)
|
|
|
|
// Listen for the interrupt signal.
|
|
<-ctx.Done()
|
|
|
|
stop()
|
|
logger.InfoContext(ctx, "shutting down gracefully, press Ctrl+C again to force")
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
defer cancel()
|
|
|
|
logger.InfoContext(ctx, "Server exiting")
|
|
|
|
return nil
|
|
}
|