about summary refs log tree commit diff
path: root/manager/manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'manager/manager.go')
-rw-r--r--manager/manager.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/manager/manager.go b/manager/manager.go
new file mode 100644
index 0000000..1a79214
--- /dev/null
+++ b/manager/manager.go
@@ -0,0 +1,57 @@
+// Copyright 2022 Terin Stock.
+// SPDX-License-Identifier: MPL-2.0
+
+package manager
+
+import (
+	"context"
+	"sync/atomic"
+
+	"golang.org/x/sync/errgroup"
+)
+
+type Manager struct {
+	started     uint32
+	runnables   []Runnable
+	internalCtx context.Context
+	group       *errgroup.Group
+}
+
+func New() *Manager {
+	return &Manager{
+		runnables: []Runnable{},
+	}
+}
+
+func (m *Manager) Add(r Runnable) error {
+	if atomic.LoadUint32(&m.started) == 1 {
+		m.group.Go(func() error {
+			return r.Start(m.internalCtx)
+		})
+	} else {
+		m.runnables = append(m.runnables, r)
+	}
+
+	return nil
+}
+
+func (m *Manager) Start(ctx context.Context) error {
+	g, internalCtx := errgroup.WithContext(ctx)
+	m.group = g
+	m.internalCtx = internalCtx
+
+	atomic.SwapUint32(&m.started, 1)
+	for _, r := range m.runnables {
+		r := r
+		g.Go(func() error {
+			return r.Start(internalCtx)
+		})
+	}
+	m.runnables = nil
+
+	return g.Wait()
+}
+
+type Runnable interface {
+	Start(ctx context.Context) error
+}