@@ -0,0 +1,145 @@
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user