Skip to content

Commit

Permalink
feat: run instance pruning every 6h
Browse files Browse the repository at this point in the history
  • Loading branch information
WoodenMaiden committed May 7, 2024
1 parent 38ff0ed commit 03512aa
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 14 deletions.
24 changes: 15 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
"log"
"context"
"log"
"time"

"github.com/do4-2022/grobuzin/database"
"github.com/do4-2022/grobuzin/routes"
// "github.com/do4-2022/grobuzin/scheduler"
"github.com/do4-2022/grobuzin/scheduler"

"github.com/caarlos0/env/v10"

Expand Down Expand Up @@ -34,21 +35,26 @@ func main() {
}

ctx := context.Background()

/*
redis := database.InitRedis(cfg.VMStateURL)

s := &scheduler.Scheduler{
RedisHandle: redis,
Redis: redis,
Context: &ctx,
}*/
}
//Now inject the scheduler into the routes that need it!

go func() {
// every 24 hours we check for
for {
time.Sleep(time.Hour * 6);

log.Println("Ran instance pruning at", time.Now().UTC())
s.FindAndDestroyUnsused(24);
}
}()

db := database.Init(cfg.FuntionStateStorageDSN)
r := routes.GetRoutes(db, cfg.JWTSecret, getMinioClient(cfg))
redis := database.InitRedis(cfg.VMStateURL)
redis.Ping(ctx) // TODO define scheduler struct


err := r.Run()

Expand Down
50 changes: 45 additions & 5 deletions scheduler/scheduler.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package scheduler

import (
"errors"
"context"
"errors"
"fmt"
"time"

"github.com/google/uuid"
"github.com/redis/go-redis/v9"
Expand All @@ -18,6 +19,9 @@ const (
Unknown
)

// This struct represents an instance of a function, especially it's address and status
// Each key in the redis is namespaced as it follows:
// <id of the function>:<id of the instance>
type FunctionLocation struct {
Address string `redis:"address"`
Port uint16 `redis:"port"`
Expand All @@ -34,6 +38,7 @@ type Scheduler struct {

// Uses SCAN to look for the first instance marked as ready (https://redis.io/docs/latest/commands/scan/)
func (s *Scheduler) LookForReadyInstance(functionId uuid.UUID, cursor uint64) (id string, returnedCursor uint64, err error) {
// match rule to get all instances of a function
locationMatch := fmt.Sprintf(functionId.String(), ":*")

keys, returnedCursor, err := s.Redis.Scan(*s.Context, cursor, locationMatch, 10).Result()
Expand Down Expand Up @@ -80,13 +85,16 @@ func (s *Scheduler) SpawnVM(functionId uuid.UUID) (LambdoRunResponse, err error)

func (s *Scheduler) GetFunctionLocations(functionId uuid.UUID) (locations []FunctionLocation) {
locationQuery := fmt.Sprintf(functionId.String(), ":*")
firstsweep, cursor := true, uint64(0)

// because do-while does not exists in these lands
for !firstsweep && cursor != 0 {
firstsweep = false


// because while does not exists in these lands
for ok, cursor := true, uint64(0) ; ok; ok = (cursor != 0) {
var keys []string
keys, cursor = s.Redis.Scan(*s.Context, cursor, locationQuery, 10).Val()

// for each key we got, we retrieve all of it's information
for _, ID := range keys {
var location FunctionLocation

Expand All @@ -99,4 +107,36 @@ func (s *Scheduler) GetFunctionLocations(functionId uuid.UUID) (locations []Func
}

return
}
}

// goes through the whole redis instance and remove that have not been used within the last {hoursTimeout} Hours
func (s *Scheduler) FindAndDestroyUnsused(hoursTimeout float64) {
now := time.Now()
keys, cursor := s.Redis.Scan(*s.Context, 0, "*", 10).Val()

for cursor != 0 {
for _, ID := range keys {
val, err := s.Redis.HGet(*s.Context, ID, "lastUsed").Result()

if err != nil {
continue
}

// if it was never used we delete this
if val == "never" {
if s.Lambdo.DeleteVM(ID) != nil {
s.Redis.Del(*s.Context, ID)
}
} else {
// if it hasn't been used for {hoursTimeout} we delete it
lastUsed, err := time.Parse(time.UnixDate, val)
if err != nil || now.Sub(lastUsed).Abs().Hours() >= hoursTimeout {
if s.Lambdo.DeleteVM(ID) != nil {
s.Redis.Del(*s.Context, ID)
}
}
}
}
keys, cursor = s.Redis.Scan(*s.Context, cursor, "*", 10).Val()
}
}

0 comments on commit 03512aa

Please sign in to comment.