fix(pkg/sensor): reduce interface functions for better error handling

This commit is contained in:
2020-01-10 19:42:19 +01:00
parent ca4269fff8
commit 95fb1f6745
12 changed files with 159 additions and 93 deletions

View File

@ -1,58 +1,46 @@
package sensor
import (
"context"
"fmt"
"sync"
"github.com/go-flucky/flucky/pkg/internal/collect"
"github.com/go-flucky/flucky/pkg/internal/prittyprint"
"github.com/go-flucky/flucky/pkg/types"
)
// Read measured values from sensors
func Read(ctx context.Context, sensors []Sensor) ([]*types.MeasuredValue, error) {
func Read(sensors []Sensor, measuredValueType types.MeasuredValueType) ([]*types.MeasuredValue, error) {
measuredValueChannel := make(chan *types.MeasuredValue, len(sensors))
errorChannel := make(chan error, len(sensors))
ReadChannel(ctx, sensors, measuredValueChannel, errorChannel)
errors := collect.Errors(errorChannel)
if len(errors) > 0 {
return nil, prittyprint.FormatErrors(errors)
type result struct {
measuredValues []*types.MeasuredValue
err error
}
measuredValues := collect.MeasuredValues(measuredValueChannel)
resultChannel := make(chan *result, len(sensors))
return measuredValues, nil
}
// ReadChannel reads the measured values from sensors and writes them to a
// channel.
func ReadChannel(ctx context.Context, sensors []Sensor, measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error) {
wg := new(sync.WaitGroup)
wg.Add(len(sensors))
for _, sensor := range sensors {
go sensor.ReadChannel(measuredValueChannel, errorChannel, wg)
// producers
// read measured values
for _, s := range sensors {
go func(s Sensor) {
measuredValues, err := s.Read()
resultChannel <- &result{
measuredValues: measuredValues,
err: err,
}
}(s)
}
wg.Wait()
}
// ReadContinuously reads the measured values continously from sensors and writes
// them to a channel.
func ReadContinuously(ctx context.Context, sensors []Sensor, measuredValueChannel chan<- *types.MeasuredValue, errorChannel chan<- error) {
// consumer
measuredValues := make([]*types.MeasuredValue, 0)
counter := len(sensors)
for {
if counter == 0 {
break
}
select {
case <-ctx.Done():
errorChannel <- fmt.Errorf("Context closed: %v", ctx.Err())
return
default:
ReadChannel(ctx, sensors, measuredValueChannel, errorChannel)
case result := <-resultChannel:
counter--
if result.err != nil {
return nil, result.err
}
measuredValues = append(measuredValues, result.measuredValues...)
}
}
return types.SelectMeasuredValues(measuredValueType, measuredValues), nil
}