125 lines
2.6 KiB
Go
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)
|
|
}
|
|
}
|