Files
go-receipt-tracker/workers/workers.go
2025-02-03 17:49:29 -05:00

125 lines
2.6 KiB
Go

package workers
import (
"log/slog"
"sync"
)
type Config struct {
// TLSConfig is a tls.Config configuration to be used with the listener.
// See examples folder for basic and mutual-tls use.
Test string
}
// EstablishFn is a callback function for establishing new clients.
type EstablishFn func(id string) error
// CloseFn is a callback function for closing all listener clients.
type CloseFn func(id string)
// Worker .
type Worker interface {
ID() string // returns ID in string format
Type() string // returns the type of the worker
Init(*slog.Logger) error //
OneTime() error //
Serve() // starting actively listening for new connections
Close() // stop and close the worker
}
// Workers contains the network workers for the app.
type Workers struct {
ClientsWg sync.WaitGroup // a waitgroup that waits for all clients in all workers to finish.
internal map[string]Worker // a map of active workers.
sync.RWMutex
}
// New returns a new instance of Workers.
func New() *Workers {
return &Workers{
internal: map[string]Worker{},
}
}
// Add adds a new worker to the workers map, keyed on id.
func (w *Workers) Add(val Worker) {
w.Lock()
defer w.Unlock()
w.internal[val.ID()] = val
}
// Get returns the value of a worker if it exists.
func (w *Workers) Get(id string) (Worker, bool) {
w.RLock()
defer w.RUnlock()
val, ok := w.internal[id]
return val, ok
}
// Len returns the length of the workers map.
func (w *Workers) Len() int {
w.RLock()
defer w.RUnlock()
return len(w.internal)
}
// Delete removes a worker from the internal map.
func (w *Workers) Delete(id string) {
w.Lock()
defer w.Unlock()
delete(w.internal, id)
}
// Serve starts a worker serving from the internal map.
func (w *Workers) Serve(id string) {
w.RLock()
defer w.RUnlock()
worker := w.internal[id]
go func() {
worker.Serve()
worker.OneTime()
}()
}
// ServeAll starts all workers serving from the internal map.
func (w *Workers) ServeAll() {
w.RLock()
i := 0
ids := make([]string, len(w.internal))
for id := range w.internal {
ids[i] = id
i++
}
w.RUnlock()
for _, id := range ids {
w.Serve(id)
}
}
// Close stops a worker from the internal map.
func (w *Workers) Close(id string) {
w.RLock()
defer w.RUnlock()
if worker, ok := w.internal[id]; ok {
worker.Close()
}
}
// CloseAll iterates and closes all registered workere.
func (w *Workers) CloseAll() {
w.RLock()
i := 0
ids := make([]string, len(w.internal))
for id := range w.internal {
ids[i] = id
i++
}
w.RUnlock()
for _, id := range ids {
w.Close(id)
}
}