Files
sablier/app/discovery/autostop.go
Alexis Couvreur f29b13a55a refactor(storage): add store.Store interface
There is a first implementation with ValKey that will allow to use redis APIs as a backend for Sablier with Hight Availability
2025-02-02 18:13:45 -05:00

63 lines
2.1 KiB
Go

package discovery
import (
"context"
"errors"
"github.com/sablierapp/sablier/app/providers"
"github.com/sablierapp/sablier/pkg/store"
log "github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)
// StopAllUnregisteredInstances stops all auto-discovered running instances that are not yet registered
// as running instances by Sablier.
// By default, Sablier does not stop all already running instances. Meaning that you need to make an
// initial request in order to trigger the scaling to zero.
func StopAllUnregisteredInstances(ctx context.Context, provider providers.Provider, s store.Store) error {
log.Info("Stopping all unregistered running instances")
log.Tracef("Retrieving all instances with label [%v=true]", LabelEnable)
instances, err := provider.InstanceList(ctx, providers.InstanceListOptions{
All: false, // Only running containers
Labels: []string{LabelEnable},
})
if err != nil {
return err
}
log.Tracef("Found %v instances with label [%v=true]", len(instances), LabelEnable)
unregistered := make([]string, 0)
for _, instance := range instances {
_, err = s.Get(ctx, instance.Name)
if errors.Is(err, store.ErrKeyNotFound) {
unregistered = append(unregistered, instance.Name)
}
}
log.Tracef("Found %v unregistered instances ", len(instances))
waitGroup := errgroup.Group{}
// Previously, the variables declared by a “for” loop were created once and updated by each iteration.
// In Go 1.22, each iteration of the loop creates new variables, to avoid accidental sharing bugs.
// The transition support tooling described in the proposal continues to work in the same way it did in Go 1.21.
for _, name := range unregistered {
waitGroup.Go(stopFunc(ctx, name, provider))
}
return waitGroup.Wait()
}
func stopFunc(ctx context.Context, name string, provider providers.Provider) func() error {
return func() error {
log.Tracef("Stopping %v...", name)
err := provider.Stop(ctx, name)
if err != nil {
log.Errorf("Could not stop %v: %v", name, err)
return err
}
log.Tracef("Successfully stopped %v", name)
return nil
}
}