| |
| |
| package strategy |
|
|
| import ( |
| "context" |
| "fmt" |
| "net/http" |
| "sync" |
|
|
| "github.com/pinchtab/pinchtab/internal/config" |
| "github.com/pinchtab/pinchtab/internal/orchestrator" |
| ) |
|
|
| |
| |
| type Orchestrator interface { |
| RegisterHandlers(mux *http.ServeMux) |
| FirstRunningURL() string |
| } |
|
|
| |
| |
| |
| type OrchestratorAware interface { |
| SetOrchestrator(o *orchestrator.Orchestrator) |
| } |
|
|
| |
| |
| type RuntimeConfigAware interface { |
| SetRuntimeConfig(cfg *config.RuntimeConfig) |
| } |
|
|
| |
| type Strategy interface { |
| |
| Name() string |
|
|
| |
| RegisterRoutes(mux *http.ServeMux) |
|
|
| |
| Start(ctx context.Context) error |
|
|
| |
| Stop() error |
| } |
|
|
| |
| type Factory func() Strategy |
|
|
| var ( |
| registry = make(map[string]Factory) |
| mu sync.RWMutex |
| ) |
|
|
| |
| func Register(name string, factory Factory) error { |
| mu.Lock() |
| defer mu.Unlock() |
| if _, exists := registry[name]; exists { |
| return fmt.Errorf("strategy %q already registered", name) |
| } |
| registry[name] = factory |
| return nil |
| } |
|
|
| |
| func MustRegister(name string, factory Factory) { |
| if err := Register(name, factory); err != nil { |
| panic(err) |
| } |
| } |
|
|
| |
| func New(name string) (Strategy, error) { |
| mu.RLock() |
| factory, ok := registry[name] |
| mu.RUnlock() |
|
|
| if !ok { |
| return nil, fmt.Errorf("unknown strategy: %s (available: %v)", name, Names()) |
| } |
| return factory(), nil |
| } |
|
|
| |
| func Names() []string { |
| mu.RLock() |
| defer mu.RUnlock() |
|
|
| names := make([]string, 0, len(registry)) |
| for name := range registry { |
| names = append(names, name) |
| } |
| return names |
| } |
|
|