added mutex for sparkline cleanup function in order to eliminate possibility of clash with Draw function

This commit is contained in:
sqshq 2019-04-21 00:15:03 -04:00
parent 892f2322d2
commit 846ced69d9
3 changed files with 16 additions and 8 deletions

View File

@ -187,7 +187,6 @@ func (c *RunChart) consumeSample(sample *data.Sample) {
line.points = append(line.points, c.newTimePoint(float)) line.points = append(line.points, c.newTimePoint(float))
c.lines[index] = line c.lines[index] = line
// perform cleanup once in a while
if len(line.points)%100 == 0 { if len(line.points)%100 == 0 {
c.trimOutOfRangeValues() c.trimOutOfRangeValues()
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data" "github.com/sqshq/sampler/data"
"image" "image"
"sync"
) )
type SparkLine struct { type SparkLine struct {
@ -20,6 +21,7 @@ type SparkLine struct {
scale int scale int
gradient []ui.Color gradient []ui.Color
palette console.Palette palette console.Palette
mutex *sync.Mutex
} }
func NewSparkLine(c config.SparkLineConfig, palette console.Palette) *SparkLine { func NewSparkLine(c config.SparkLineConfig, palette console.Palette) *SparkLine {
@ -31,6 +33,7 @@ func NewSparkLine(c config.SparkLineConfig, palette console.Palette) *SparkLine
scale: *c.Scale, scale: *c.Scale,
gradient: *c.Gradient, gradient: *c.Gradient,
palette: palette, palette: palette,
mutex: &sync.Mutex{},
} }
go func() { go func() {
@ -78,11 +81,13 @@ func (s *SparkLine) consumeSample(sample *data.Sample) {
s.minValue = min s.minValue = min
if len(s.values)%100 == 0 { if len(s.values)%100 == 0 {
s.cleanup(s.Dx()) s.mutex.Lock()
s.trimOutOfRangeValues(s.Dx())
s.mutex.Unlock()
} }
} }
func (s *SparkLine) cleanup(maxSize int) { func (s *SparkLine) trimOutOfRangeValues(maxSize int) {
if maxSize < len(s.values) { if maxSize < len(s.values) {
s.values = append(s.values[:0], s.values[len(s.values)-maxSize:]...) s.values = append(s.values[:0], s.values[len(s.values)-maxSize:]...)
} }
@ -90,6 +95,8 @@ func (s *SparkLine) cleanup(maxSize int) {
func (s *SparkLine) Draw(buffer *ui.Buffer) { func (s *SparkLine) Draw(buffer *ui.Buffer) {
s.mutex.Lock()
textStyle := ui.NewStyle(s.palette.BaseColor) textStyle := ui.NewStyle(s.palette.BaseColor)
height := s.Dy() - 2 height := s.Dy() - 2
@ -131,6 +138,8 @@ func (s *SparkLine) Draw(buffer *ui.Buffer) {
} }
} }
s.mutex.Unlock()
s.Block.Draw(buffer) s.Block.Draw(buffer)
component.RenderAlert(s.alert, s.Rectangle, buffer) component.RenderAlert(s.alert, s.Rectangle, buffer)
} }

View File

@ -4,7 +4,7 @@ import (
"testing" "testing"
) )
func TestSparkLine_cleanup(t *testing.T) { func TestSparkLine_trimOutOfRangeValues(t *testing.T) {
type Sparkline struct { type Sparkline struct {
maxSize int maxSize int
expectedSize int expectedSize int
@ -14,17 +14,17 @@ func TestSparkLine_cleanup(t *testing.T) {
name string name string
sparkline Sparkline sparkline Sparkline
}{ }{
{"should cleanup values to the max size", Sparkline{maxSize: 5, expectedSize: 5, values: []float64{1, 2, 3, 4, 5, 6, 7, 8}}}, {"should trimOutOfRangeValues values to the max size", Sparkline{maxSize: 5, expectedSize: 5, values: []float64{1, 2, 3, 4, 5, 6, 7, 8}}},
{"should not cleanup values if max size is bigger than values len", Sparkline{maxSize: 5, expectedSize: 3, values: []float64{1, 2, 3}}}, {"should not trimOutOfRangeValues values if max size is bigger than values len", Sparkline{maxSize: 5, expectedSize: 3, values: []float64{1, 2, 3}}},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s := &SparkLine{ s := &SparkLine{
values: tt.sparkline.values, values: tt.sparkline.values,
} }
s.cleanup(tt.sparkline.maxSize) s.trimOutOfRangeValues(tt.sparkline.maxSize)
if len(s.values) != tt.sparkline.expectedSize { if len(s.values) != tt.sparkline.expectedSize {
t.Errorf("Values size after cleanup is %v, but needed to be %v", len(s.values), tt.sparkline.expectedSize) t.Errorf("Values size after trimOutOfRangeValues is %v, but needed to be %v", len(s.values), tt.sparkline.expectedSize)
} }
}) })
} }