You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-25 22:41:46 +02:00
Add queue for BatchingProcessor (#5131)
This commit is contained in:
@@ -4,7 +4,9 @@
|
||||
package log // import "go.opentelemetry.io/otel/sdk/log"
|
||||
|
||||
import (
|
||||
"container/ring"
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -76,6 +78,91 @@ func (b *BatchingProcessor) ForceFlush(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// queue holds a queue of logging records.
|
||||
//
|
||||
// When the queue becomes full, the oldest records in the queue are
|
||||
// overwritten.
|
||||
type queue struct {
|
||||
sync.Mutex
|
||||
|
||||
cap, len int
|
||||
read, write *ring.Ring
|
||||
}
|
||||
|
||||
func newQueue(size int) *queue {
|
||||
r := ring.New(size)
|
||||
return &queue{
|
||||
cap: size,
|
||||
read: r,
|
||||
write: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue adds r to the queue. The queue size, including the addition of r, is
|
||||
// returned.
|
||||
//
|
||||
// If enqueueing r will exceed the capacity of q, the oldest Record held in q
|
||||
// will be dropped and r retained.
|
||||
func (q *queue) Enqueue(r Record) int {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
|
||||
q.write.Value = r
|
||||
q.write = q.write.Next()
|
||||
|
||||
q.len++
|
||||
if q.len > q.cap {
|
||||
// Overflow. Advance read to be the new "oldest".
|
||||
q.len = q.cap
|
||||
q.read = q.read.Next()
|
||||
}
|
||||
return q.len
|
||||
}
|
||||
|
||||
// TryDequeue attempts to dequeue up to len(buf) Records. The available Records
|
||||
// will be assigned into buf and passed to write. If write fails, returning
|
||||
// false, the Records will not be removed from the queue. If write succeeds,
|
||||
// returning true, the dequeued Records are removed from the queue. The number
|
||||
// of Records remaining in the queue are returned.
|
||||
//
|
||||
// When write is called the lock of q is held. The write function must not call
|
||||
// other methods of this q that acquire the lock.
|
||||
func (q *queue) TryDequeue(buf []Record, write func([]Record) bool) int {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
|
||||
origRead := q.read
|
||||
|
||||
n := min(len(buf), q.len)
|
||||
for i := 0; i < n; i++ {
|
||||
buf[i] = q.read.Value.(Record)
|
||||
q.read = q.read.Next()
|
||||
}
|
||||
|
||||
if write(buf[:n]) {
|
||||
q.len -= n
|
||||
} else {
|
||||
q.read = origRead
|
||||
}
|
||||
return q.len
|
||||
}
|
||||
|
||||
// Flush returns all the Records held in the queue and resets it to be
|
||||
// empty.
|
||||
func (q *queue) Flush() []Record {
|
||||
q.Lock()
|
||||
defer q.Unlock()
|
||||
|
||||
out := make([]Record, q.len)
|
||||
for i := range out {
|
||||
out[i] = q.read.Value.(Record)
|
||||
q.read = q.read.Next()
|
||||
}
|
||||
q.len = 0
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type batchingConfig struct {
|
||||
maxQSize setting[int]
|
||||
expInterval setting[time.Duration]
|
||||
|
||||
Reference in New Issue
Block a user