File size: 2,538 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | package instance
import (
"fmt"
"sync"
"github.com/pinchtab/pinchtab/internal/bridge"
)
// Repository manages the in-memory store of instances and delegates
// process lifecycle to an InstanceLauncher (typically the Orchestrator).
type Repository struct {
mu sync.RWMutex
instances map[string]*bridge.Instance
launcher InstanceLauncher
}
// NewRepository creates a Repository backed by the given launcher.
func NewRepository(launcher InstanceLauncher) *Repository {
return &Repository{
instances: make(map[string]*bridge.Instance),
launcher: launcher,
}
}
// Launch starts a new instance and adds it to the store.
func (r *Repository) Launch(name, port string, headless bool) (*bridge.Instance, error) {
inst, err := r.launcher.Launch(name, port, headless)
if err != nil {
return nil, fmt.Errorf("launch instance: %w", err)
}
r.mu.Lock()
r.instances[inst.ID] = inst
r.mu.Unlock()
return inst, nil
}
// Stop terminates an instance and removes it from the store.
func (r *Repository) Stop(id string) error {
if err := r.launcher.Stop(id); err != nil {
return fmt.Errorf("stop instance %q: %w", id, err)
}
r.mu.Lock()
delete(r.instances, id)
r.mu.Unlock()
return nil
}
// List returns all instances. The returned slice is a snapshot.
func (r *Repository) List() []bridge.Instance {
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]bridge.Instance, 0, len(r.instances))
for _, inst := range r.instances {
out = append(out, *inst)
}
return out
}
// Running returns only instances with status "running".
func (r *Repository) Running() []bridge.Instance {
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]bridge.Instance, 0, len(r.instances))
for _, inst := range r.instances {
if inst.Status == "running" {
out = append(out, *inst)
}
}
return out
}
// Get returns an instance by ID.
func (r *Repository) Get(id string) (*bridge.Instance, bool) {
r.mu.RLock()
defer r.mu.RUnlock()
inst, ok := r.instances[id]
if !ok {
return nil, false
}
copy := *inst
return ©, true
}
// Add registers an existing instance (used for sync with external state).
func (r *Repository) Add(inst *bridge.Instance) {
r.mu.Lock()
r.instances[inst.ID] = inst
r.mu.Unlock()
}
// Remove deletes an instance from the store without stopping it.
func (r *Repository) Remove(id string) {
r.mu.Lock()
delete(r.instances, id)
r.mu.Unlock()
}
// Count returns the number of tracked instances.
func (r *Repository) Count() int {
r.mu.RLock()
defer r.mu.RUnlock()
return len(r.instances)
}
|