@@ -43,8 +43,10 @@ type Leaky struct {
4343 CacheSize int
4444 // the unique identifier of the bucket (a hash)
4545 Mapkey string
46- // chan for signaling
47- Signal chan bool `json:"-"`
46+ ready chan struct {} // closed when LeakRoutine is ready
47+ readyOnce sync.Once // use to prevent double close
48+ done chan struct {} // closed when LeakRoutine has stopped processing
49+ doneOnce sync.Once // use to prevent double close
4850 Suicide chan bool `json:"-"`
4951 Reprocess bool
5052 Simulated bool
@@ -150,6 +152,8 @@ func (l *Leaky) LeakRoutine(ctx context.Context, gate pourGate) {
150152 firstEvent = true
151153 )
152154
155+ defer l .markDone ()
156+
153157 defer func () {
154158 if durationTicker != nil {
155159 durationTicker .Stop ()
@@ -170,13 +174,12 @@ func (l *Leaky) LeakRoutine(ctx context.Context, gate pourGate) {
170174 // and preventing them from being destroyed
171175 processors := deepcopy .Copy (l .BucketConfig .processors ).([]Processor )
172176
173- l .Signal <- true
177+ l .markReady ()
174178
175179 for _ , f := range processors {
176180 err := f .OnBucketInit (l .BucketConfig )
177181 if err != nil {
178182 l .logger .Errorf ("Problem at bucket initializiation. Bail out %T : %v" , f , err )
179- close (l .Signal )
180183 return
181184 }
182185 }
@@ -237,7 +240,8 @@ func (l *Leaky) LeakRoutine(ctx context.Context, gate pourGate) {
237240 return
238241 // suiciiiide
239242 case <- l .Suicide :
240- close (l .Signal )
243+ // don't wait defer to close the channel, in case we are blocked before returning
244+ l .markDone ()
241245 metrics .BucketsCanceled .With (prometheus.Labels {"name" : l .Name }).Inc ()
242246 l .logger .Debugf ("Suicide triggered" )
243247 l .AllOut <- pipeline.Event {Type : pipeline .OVFLW , Overflow : pipeline.RuntimeAlert {Mapkey : l .Mapkey }}
@@ -250,7 +254,7 @@ func (l *Leaky) LeakRoutine(ctx context.Context, gate pourGate) {
250254 err error
251255 )
252256 l .Ovflw_ts = time .Now ().UTC ()
253- close ( l . Signal )
257+ l . markDone ( )
254258 ofw := l .Queue
255259 alert = pipeline.RuntimeAlert {Mapkey : l .Mapkey }
256260
@@ -316,7 +320,7 @@ func Pour(l *Leaky, gate pourGate, msg pipeline.Event) {
316320}
317321
318322func (l * Leaky ) overflow (ofw * pipeline.Queue ) {
319- close ( l . Signal )
323+ l . markDone ( )
320324 alert , err := NewAlert (l , ofw )
321325 if err != nil {
322326 log .Errorf ("%s" , err )
@@ -339,3 +343,16 @@ func (l *Leaky) overflow(ofw *pipeline.Queue) {
339343
340344 l .AllOut <- pipeline.Event {Overflow : alert , Type : pipeline .OVFLW , MarshaledTime : string (mt )}
341345}
346+
347+ func (l * Leaky ) markReady () {
348+ l .readyOnce .Do (func () {
349+ close (l .ready )
350+ })
351+ }
352+
353+ func (l * Leaky ) markDone () {
354+ l .doneOnce .Do (func () {
355+ close (l .done )
356+ })
357+ }
358+
0 commit comments