Files
omnex/control-plane/api/internal/demos/mem.go
T
Nuxgrid 4b3a5720a3
ci-api / test (push) Has been cancelled
feat: add details demo
2026-07-28 14:44:48 +02:00

158 lines
3.1 KiB
Go

package demos
import "sync"
// MemStore : Store en mémoire (dev/tests).
type MemStore struct {
mu sync.RWMutex
items map[string]Demo
}
func NewMemStore() *MemStore { return &MemStore{items: make(map[string]Demo)} }
func (m *MemStore) Create(d Demo) (Demo, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.items[d.ID] = d
return d, nil
}
func (m *MemStore) Get(id string) (Demo, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
d, ok := m.items[id]
return d, ok
}
func (m *MemStore) List() ([]Demo, error) {
m.mu.RLock()
defer m.mu.RUnlock()
out := make([]Demo, 0, len(m.items))
for _, d := range m.items {
out = append(out, d)
}
return out, nil
}
func (m *MemStore) ListByUsername(username string) ([]Demo, error) {
m.mu.RLock()
defer m.mu.RUnlock()
out := make([]Demo, 0)
for _, d := range m.items {
if d.Username == username {
out = append(out, d)
}
}
return out, nil
}
func (m *MemStore) Update(d Demo) (Demo, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.items[d.ID] = d
return d, nil
}
func (m *MemStore) CountActive() (int, error) {
m.mu.RLock()
defer m.mu.RUnlock()
n := 0
for _, d := range m.items {
if d.Status.Active() {
n++
}
}
return n, nil
}
func (m *MemStore) GetDemoByUsername(username string) (Demo, error) {
m.mu.Lock()
defer m.mu.Unlock()
for _, demo := range m.items {
if demo.Username == username {
return demo, nil
}
}
return Demo{}, ErrNotFound
}
// MemPool : Pool en mémoire (dev/tests), PoolSizePerService slots par service.
type MemPool struct {
mu sync.Mutex
res []*ExternalResource
next uint
}
// NewMemPool construit un pool rempli (PoolSizePerService slots libres par service).
func NewMemPool() *MemPool {
p := &MemPool{}
for _, svc := range PooledServices {
for i := 1; i <= PoolSizePerService; i++ {
p.next++
p.res = append(p.res, &ExternalResource{
ID: p.next,
Service: svc,
Label: placeholderLabel(svc, i),
SecretRef: "secretref://" + svc + "/slot-" + itoa(i),
Status: ResourceFree,
})
}
}
return p
}
func (p *MemPool) Borrow(demoID string) ([]ExternalResource, error) {
p.mu.Lock()
defer p.mu.Unlock()
// Vérifie d'abord la dispo de chaque service (atomicité).
pick := make(map[string]*ExternalResource, len(PooledServices))
for _, svc := range PooledServices {
var found *ExternalResource
for _, r := range p.res {
if r.Service == svc && r.Status == ResourceFree {
found = r
break
}
}
if found == nil {
return nil, ErrPoolExhausted
}
pick[svc] = found
}
var out []ExternalResource
for _, r := range pick {
r.Status = ResourceBorrowed
r.DemoID = demoID
out = append(out, *r)
}
return out, nil
}
func (p *MemPool) Return(demoID string) error {
p.mu.Lock()
defer p.mu.Unlock()
for _, r := range p.res {
if r.DemoID == demoID {
r.Status = ResourceFree
r.DemoID = ""
}
}
return nil
}
func (p *MemPool) FreeCount() (map[string]int, error) {
p.mu.Lock()
defer p.mu.Unlock()
out := map[string]int{}
for _, svc := range PooledServices {
out[svc] = 0
}
for _, r := range p.res {
if r.Status == ResourceFree {
out[r.Service]++
}
}
return out, nil
}