working on valuemonitor
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ValueMonitorParseFunc[T any] func(string) (T, error)
|
||||
|
||||
type ValueMonitor[T any] struct {
|
||||
mutex sync.RWMutex
|
||||
parent *Settings
|
||||
updates <-chan string
|
||||
key string
|
||||
parserFunc ValueMonitorParseFunc[T]
|
||||
value T
|
||||
}
|
||||
|
||||
func (v *ValueMonitor[T]) GetValue() T {
|
||||
v.mutex.RLock()
|
||||
defer v.mutex.RUnlock()
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *ValueMonitor[T]) maintenanceThread() {
|
||||
ctx := v.parent.context
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case s, ok := <-v.updates:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
t, err := v.parserFunc(s)
|
||||
if err != nil {
|
||||
log.Printf("ValueMonitor error parsing key %q value %q from channel: %v\n", v.key, s, err)
|
||||
continue
|
||||
}
|
||||
func() {
|
||||
v.mutex.RLock()
|
||||
defer v.mutex.RUnlock()
|
||||
v.value = t
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewValueMonitor[T any](settings *Settings, key string, parserFunc ValueMonitorParseFunc[T]) (*ValueMonitor[T], error) {
|
||||
monitorChannel := make(chan string, 1)
|
||||
err := settings.RegisterKeyToMonitor(key, monitorChannel)
|
||||
if err != nil {
|
||||
close(monitorChannel)
|
||||
return nil, fmt.Errorf("error registering ValueMonitor %w", err)
|
||||
}
|
||||
initialString, ok := <-monitorChannel
|
||||
if !ok {
|
||||
close(monitorChannel)
|
||||
return nil, errors.New("channel closed before reading initial value")
|
||||
}
|
||||
parsed, err := parserFunc(initialString)
|
||||
if err != nil {
|
||||
close(monitorChannel)
|
||||
return nil, fmt.Errorf("error parsing initial value from %q: %v", initialString, err)
|
||||
}
|
||||
go func() {
|
||||
<-settings.context.Done()
|
||||
close(monitorChannel)
|
||||
}()
|
||||
results := &ValueMonitor[T]{
|
||||
parent: settings,
|
||||
updates: monitorChannel,
|
||||
key: key,
|
||||
parserFunc: parserFunc,
|
||||
value: parsed,
|
||||
}
|
||||
go results.maintenanceThread()
|
||||
return results, nil
|
||||
}
|
||||
Reference in New Issue
Block a user