Improved perfs
This commit is contained in:
@@ -5,6 +5,7 @@ package stub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand/v2"
|
||||
"sync"
|
||||
@@ -13,11 +14,12 @@ import (
|
||||
"github.com/uopi/uopi/internal/datasource"
|
||||
)
|
||||
|
||||
const updateInterval = 100 * time.Millisecond // 10 Hz
|
||||
const updateInterval = 100 * time.Millisecond // 10 Hz default
|
||||
|
||||
type signalDef struct {
|
||||
meta datasource.Metadata
|
||||
fn func(t time.Time) any
|
||||
meta datasource.Metadata
|
||||
interval time.Duration // 0 → updateInterval
|
||||
fn func(t time.Time) any
|
||||
}
|
||||
|
||||
// Stub is a data source that emits canned signals for development and testing.
|
||||
@@ -96,6 +98,41 @@ func New() *Stub {
|
||||
fn: func(t time.Time) any { return 25.0 }, // default; overwritten by Write
|
||||
})
|
||||
s.values["setpoint"] = 25.0
|
||||
s.register(signalDef{
|
||||
meta: datasource.Metadata{
|
||||
Name: "counter_fast", Type: datasource.TypeFloat64,
|
||||
Description: "Fast monotonic counter (1 ms tick) for benchmarks",
|
||||
},
|
||||
interval: time.Millisecond,
|
||||
fn: func(t time.Time) any { return float64(t.UnixMilli()) },
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
// NewN creates a Stub with n dynamically generated signals named "pv_0" … "pv_{n-1}".
|
||||
// Each signal is a sine wave at a distinct frequency, emitted at 10 Hz.
|
||||
// Use this for stress and scale testing.
|
||||
func NewN(n int) *Stub {
|
||||
s := &Stub{
|
||||
signals: make(map[string]signalDef),
|
||||
values: make(map[string]any),
|
||||
}
|
||||
for i := range n {
|
||||
freq := 0.1 + float64(i)*0.01 // spread frequencies so signals differ
|
||||
s.register(signalDef{
|
||||
meta: datasource.Metadata{
|
||||
Name: fmt.Sprintf("pv_%d", i),
|
||||
Type: datasource.TypeFloat64,
|
||||
Unit: "V",
|
||||
DisplayLow: -1,
|
||||
DisplayHigh: 1,
|
||||
Description: fmt.Sprintf("Synthetic PV #%d (%.2f Hz sine)", i, freq),
|
||||
},
|
||||
fn: func(t time.Time) any {
|
||||
return math.Sin(2 * math.Pi * freq * float64(t.UnixNano()) / 1e9)
|
||||
},
|
||||
})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -127,16 +164,22 @@ func (s *Stub) GetMetadata(_ context.Context, signal string) (datasource.Metadat
|
||||
return d.meta, nil
|
||||
}
|
||||
|
||||
// Subscribe starts a 10 Hz ticker that pushes generated values into ch.
|
||||
// Subscribe starts a ticker that pushes generated values into ch.
|
||||
// The tick interval is the signal's configured interval (default 10 Hz).
|
||||
func (s *Stub) Subscribe(ctx context.Context, signal string, ch chan<- datasource.Value) (datasource.CancelFunc, error) {
|
||||
def, ok := s.signals[signal]
|
||||
if !ok {
|
||||
return nil, datasource.ErrNotFound
|
||||
}
|
||||
|
||||
interval := def.interval
|
||||
if interval == 0 {
|
||||
interval = updateInterval
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
go func() {
|
||||
ticker := time.NewTicker(updateInterval)
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
|
||||
Reference in New Issue
Block a user