WiP
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
parent
8c62b6de8c
commit
bc470c5f78
5 changed files with 58 additions and 0 deletions
|
|
@ -5,6 +5,7 @@ import "time"
|
|||
// TODO(gabriel-samfira): needs owner attribute.
|
||||
type Locker interface {
|
||||
TryLock(key string) bool
|
||||
Lock(key string)
|
||||
Unlock(key string, remove bool)
|
||||
Delete(key string)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ func (k *keyMutex) TryLock(key string) bool {
|
|||
return keyMux.TryLock()
|
||||
}
|
||||
|
||||
func (k *keyMutex) Lock(key string) {
|
||||
mux, _ := k.muxes.LoadOrStore(key, &sync.Mutex{})
|
||||
keyMux := mux.(*sync.Mutex)
|
||||
keyMux.Lock()
|
||||
}
|
||||
|
||||
func (k *keyMutex) Unlock(key string, remove bool) {
|
||||
mux, ok := k.muxes.Load(key)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@ func TryLock(key string) (bool, error) {
|
|||
|
||||
return locker.TryLock(key), nil
|
||||
}
|
||||
|
||||
func Lock(key string) {
|
||||
if locker == nil {
|
||||
panic("no locker is registered")
|
||||
}
|
||||
|
||||
locker.Lock(key)
|
||||
}
|
||||
|
||||
func Unlock(key string, remove bool) error {
|
||||
if locker == nil {
|
||||
return fmt.Errorf("no locker is registered")
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ func (w *Worker) Start() (err error) {
|
|||
slog.DebugContext(w.ctx, "starting scale set worker loops", "scale_set", w.consumerID)
|
||||
go w.loop()
|
||||
go w.keepListenerAlive()
|
||||
go w.handleAutoScale()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -307,3 +308,35 @@ func (w *Worker) keepListenerAlive() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Worker) handleAutoScale() {
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-w.quit:
|
||||
return
|
||||
case <-w.ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
var desiredRunners uint
|
||||
if w.scaleSet.DesiredRunnerCount > 0 {
|
||||
desiredRunners = uint(w.scaleSet.DesiredRunnerCount)
|
||||
}
|
||||
targetRunners := min(w.scaleSet.MinIdleRunners+desiredRunners, w.scaleSet.MaxRunners)
|
||||
|
||||
currentRunners := uint(len(w.runners))
|
||||
if currentRunners == targetRunners {
|
||||
slog.DebugContext(w.ctx, "desired runner count reached", "desired_runners", targetRunners)
|
||||
continue
|
||||
}
|
||||
|
||||
if currentRunners < targetRunners {
|
||||
slog.DebugContext(w.ctx, "scaling up", "current_runners", currentRunners, "target_runners", targetRunners)
|
||||
} else {
|
||||
slog.DebugContext(w.ctx, "scaling down", "current_runners", currentRunners, "target_runners", targetRunners)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
|
||||
commonParams "github.com/cloudbase/garm-provider-common/params"
|
||||
|
||||
"github.com/cloudbase/garm/locking"
|
||||
"github.com/cloudbase/garm/params"
|
||||
"github.com/cloudbase/garm/util/github/scalesets"
|
||||
)
|
||||
|
|
@ -45,12 +46,16 @@ func (w *Worker) HandleJobsCompleted(jobs []params.ScaleSetJobMessage) error {
|
|||
Status: commonParams.InstancePendingDelete,
|
||||
RunnerStatus: params.RunnerTerminated,
|
||||
}
|
||||
|
||||
locking.Lock(job.RunnerName)
|
||||
_, err := w.store.UpdateInstance(w.ctx, job.RunnerName, runnerUpdateParams)
|
||||
if err != nil {
|
||||
if !errors.Is(err, runnerErrors.ErrNotFound) {
|
||||
locking.Unlock(job.RunnerName, false)
|
||||
return fmt.Errorf("updating runner %s: %w", job.RunnerName, err)
|
||||
}
|
||||
}
|
||||
locking.Unlock(job.RunnerName, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -68,14 +73,18 @@ func (w *Worker) HandleJobsStarted(jobs []params.ScaleSetJobMessage) error {
|
|||
RunnerStatus: params.RunnerActive,
|
||||
}
|
||||
|
||||
locking.Lock(job.RunnerName)
|
||||
_, err := w.store.UpdateInstance(w.ctx, job.RunnerName, updateParams)
|
||||
if err != nil {
|
||||
if errors.Is(err, runnerErrors.ErrNotFound) {
|
||||
slog.InfoContext(w.ctx, "runner not found; handled by some other controller?", "runner_name", job.RunnerName)
|
||||
locking.Unlock(job.RunnerName, true)
|
||||
continue
|
||||
}
|
||||
locking.Unlock(job.RunnerName, false)
|
||||
return fmt.Errorf("updating runner %s: %w", job.RunnerName, err)
|
||||
}
|
||||
locking.Unlock(job.RunnerName, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue