dont send duplicate updates

This commit is contained in:
Balakrishnan Balasubramanian 2022-06-27 11:47:54 -04:00
parent 002844cd37
commit 1fab1e0095

View File

@ -15,10 +15,15 @@ const (
Done Done
) )
type subChan struct {
c chan<- string
lastUpdateIndex int
}
type subscriberState struct { type subscriberState struct {
step Step step Step
m sync.Mutex m sync.Mutex
subChans []chan<- string sc []subChan
} }
type InvalidState struct{ Step Step } type InvalidState struct{ Step Step }
@ -82,23 +87,25 @@ func (pt *progressTracker) Publish(id string) (chan<- string, error) {
prodChanOpen := true prodChanOpen := true
ticker := time.NewTicker(100 * time.Millisecond) ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop() defer ticker.Stop()
lastUpdateIndex := 0
for range ticker.C { for range ticker.C {
done := false LoopReader:
for !done && prodChanOpen { for prodChanOpen {
select { select {
case update, prodChanOpen = <-prodChan: case update, prodChanOpen = <-prodChan:
lastUpdateIndex++
default: default:
done = true break LoopReader
} }
} }
var scs []chan<- string var scs []subChan
func() { func() {
state.m.Lock() state.m.Lock()
defer state.m.Unlock() defer state.m.Unlock()
scs = state.subChans scs = state.sc
if !prodChanOpen { if !prodChanOpen {
for _, subChan := range scs { for _, subChan := range scs {
close(subChan) close(subChan.c)
} }
state.step = Done state.step = Done
} }
@ -107,18 +114,22 @@ func (pt *progressTracker) Publish(id string) (chan<- string, error) {
return return
} }
for _, subChan := range scs { for _, subChan := range scs {
if subChan.lastUpdateIndex != lastUpdateIndex {
select { select {
case subChan <- update: case subChan.c <- update:
subChan.lastUpdateIndex = lastUpdateIndex
default: default:
} }
} }
} }
}
}() }()
return prodChan, nil return prodChan, nil
} }
func (pt *progressTracker) Subscribe(id string) <-chan string { func (pt *progressTracker) Subscribe(id string) <-chan string {
c := make(chan string, 1) c := make(chan string, 1)
sc := subChan{c: c}
var state *subscriberState var state *subscriberState
func() { func() {
pt.m.Lock() pt.m.Lock()
@ -127,7 +138,7 @@ func (pt *progressTracker) Subscribe(id string) <-chan string {
if state == nil { if state == nil {
pt.subscribers[id] = &subscriberState{ pt.subscribers[id] = &subscriberState{
step: NotStarted, step: NotStarted,
subChans: []chan<- string{c}, sc: []subChan{sc},
} }
} }
}() }()
@ -139,6 +150,6 @@ func (pt *progressTracker) Subscribe(id string) <-chan string {
if state.step == Done { if state.step == Done {
return nil return nil
} }
state.subChans = append(state.subChans, c) state.sc = append(state.sc, sc)
return c return c
} }