Initial cloud-services repo - gateway service + pkg modules

This commit is contained in:
Chris Rai
2026-01-30 23:14:52 -05:00
commit fbb820d7b3
1037 changed files with 171318 additions and 0 deletions

52
pkg/scheduler/bucket.go Normal file
View File

@@ -0,0 +1,52 @@
package scheduler
import (
"sync"
)
// Assign elements to a bucket and perform an action 12 cycles later. This can be
// used in conjunction with a cron job to perform cleanup tasks at a constant point
// in the future.
type Bucket[T any] struct {
elements [12][]T
bucket int
mutex sync.Mutex
}
type BucketInterface[T any] interface {
Process(handler func(element Bucket[T]))
Schedule(element T) error
clear()
lapse()
}
// Run a callback on each element in next bucket, then clear
func (e *Bucket[T]) Process(handler func(element T)) {
e.mutex.Lock()
defer e.mutex.Unlock()
e.lapse()
if len(e.elements[e.bucket]) > 0 {
for _, element := range e.elements[e.bucket] {
handler(element)
}
e.clear()
}
}
// Add element to a bucket to be deleted later
func (e *Bucket[T]) Schedule(element T) {
e.mutex.Lock()
defer e.mutex.Unlock()
e.elements[e.bucket] = append(e.elements[e.bucket], element)
}
// Remove all elements from current bucket
func (e *Bucket[T]) clear() {
e.elements[e.bucket] = []T{}
}
// Increment the active bucket
func (e *Bucket[T]) lapse() {
e.bucket += 1
e.bucket %= len(e.elements)
}

View File

@@ -0,0 +1,63 @@
package scheduler
import (
"testing"
"fiskerinc.com/modules/testhelper"
)
func TestBucketProcess(t *testing.T) {
bucket := Bucket[int]{}
actual := []int{}
bucket.elements[1] = []int{1, 2, 3}
double := func(element int) {
actual = append(actual, element*2)
}
bucket.Process(double)
if len(bucket.elements[1]) != 0 {
t.Errorf("Expected bucket to be clearsd after processing, but it wasn't")
}
if bucket.bucket != 1 {
t.Errorf("Expected active bucket to be incremented, but it wasn't")
}
expected := []int{2, 4, 6}
for i := 0; i < len(expected); i++ {
if actual[i] != expected[i] {
t.Errorf(testhelper.TestErrorTemplate, "Bucket.Process()", expected, actual)
}
}
}
func TestBucketLoop(t *testing.T) {
bucket := Bucket[int]{}
stub := func(element int) {}
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
bucket.Process(stub)
if bucket.bucket != 11 {
t.Errorf("Expected active bucket to be 11, got %d", bucket.bucket)
}
bucket.Process(stub)
if bucket.bucket != 0 {
t.Errorf("Expected active bucket to be 0, got %d", bucket.bucket)
}
}