Improper use of time.After can lead to memory leaks if the timer never gets a chance to fire. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
58 lines
933 B
Go
58 lines
933 B
Go
package watcher
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/cloudbase/garm/database/common"
|
|
)
|
|
|
|
type producer struct {
|
|
closed bool
|
|
mux sync.Mutex
|
|
id string
|
|
|
|
messages chan common.ChangePayload
|
|
quit chan struct{}
|
|
ctx context.Context
|
|
}
|
|
|
|
func (w *producer) Notify(payload common.ChangePayload) error {
|
|
w.mux.Lock()
|
|
defer w.mux.Unlock()
|
|
|
|
if w.closed {
|
|
return common.ErrProducerClosed
|
|
}
|
|
|
|
timer := time.NewTimer(1 * time.Second)
|
|
defer timer.Stop()
|
|
select {
|
|
case <-w.quit:
|
|
return common.ErrProducerClosed
|
|
case <-w.ctx.Done():
|
|
return common.ErrProducerClosed
|
|
case <-timer.C:
|
|
return common.ErrProducerTimeoutErr
|
|
case w.messages <- payload:
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *producer) Close() {
|
|
w.mux.Lock()
|
|
defer w.mux.Unlock()
|
|
if w.closed {
|
|
return
|
|
}
|
|
w.closed = true
|
|
close(w.messages)
|
|
close(w.quit)
|
|
}
|
|
|
|
func (w *producer) IsClosed() bool {
|
|
w.mux.Lock()
|
|
defer w.mux.Unlock()
|
|
return w.closed
|
|
}
|