1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-04-13 11:30:31 +02:00

Add proper enqueue sync

This commit is contained in:
Vladimir Mihailenco 2020-05-14 14:25:41 +03:00
parent ab19dddd0f
commit 774889cbfa

View File

@ -17,6 +17,7 @@ package trace
import ( import (
"context" "context"
"errors" "errors"
"log"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -70,9 +71,10 @@ type BatchSpanProcessor struct {
queue chan *export.SpanData queue chan *export.SpanData
dropped uint32 dropped uint32
stopWait sync.WaitGroup enqueueWait sync.WaitGroup
stopOnce sync.Once stopWait sync.WaitGroup
stopCh chan struct{} stopOnce sync.Once
stopCh chan struct{}
} }
var _ SpanProcessor = (*BatchSpanProcessor)(nil) var _ SpanProcessor = (*BatchSpanProcessor)(nil)
@ -192,45 +194,58 @@ loop:
} }
} }
// Consume queue before close to unblock enqueue and prevent go func() {
// "panic: send on closed channel". bsp.enqueueWait.Wait()
close(bsp.queue)
}()
for { for {
if !timer.Stop() {
<-timer.C
}
const waitTimeout = 30 * time.Second
timer.Reset(waitTimeout)
select { select {
case sd := <-bsp.queue: case sd := <-bsp.queue:
if sd == nil { if sd == nil {
exportSpans() exportSpans()
return return
} }
if sd.SpanContext.IsSampled() { if sd.SpanContext.IsSampled() {
batch = append(batch, sd) batch = append(batch, sd)
if len(batch) == bsp.o.MaxExportBatchSize { if len(batch) == bsp.o.MaxExportBatchSize {
exportSpans() exportSpans()
} }
} }
default: case <-timer.C:
close(bsp.queue) log.Println("bsp.enqueueWait timeout")
exportSpans()
return
} }
} }
} }
func (bsp *BatchSpanProcessor) enqueue(sd *export.SpanData) { func (bsp *BatchSpanProcessor) enqueue(sd *export.SpanData) {
bsp.enqueueWait.Add(1)
select { select {
case <-bsp.stopCh: case <-bsp.stopCh:
bsp.enqueueWait.Done()
return return
default: default:
} }
if bsp.o.BlockOnQueueFull { if bsp.o.BlockOnQueueFull {
bsp.queue <- sd bsp.queue <- sd
} else { } else {
var ok bool
select { select {
case bsp.queue <- sd: case bsp.queue <- sd:
ok = true
default: default:
ok = false
}
if !ok {
atomic.AddUint32(&bsp.dropped, 1) atomic.AddUint32(&bsp.dropped, 1)
} }
} }
bsp.enqueueWait.Done()
} }