fix: snapshot queued log entries
This commit is contained in:
+12
-2
@@ -235,7 +235,8 @@ func (q *Queue) Submit(e *LogEntry) {
|
|||||||
q.dropped.Add(1)
|
q.dropped.Add(1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
size := EstimatedBytes(e)
|
entry := cloneLogEntry(e)
|
||||||
|
size := EstimatedBytes(entry)
|
||||||
if !q.mu.TryRLock() {
|
if !q.mu.TryRLock() {
|
||||||
q.dropped.Add(1)
|
q.dropped.Add(1)
|
||||||
return
|
return
|
||||||
@@ -246,7 +247,7 @@ func (q *Queue) Submit(e *LogEntry) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case q.ch <- queuedEntry{entry: e, size: size}:
|
case q.ch <- queuedEntry{entry: entry, size: size}:
|
||||||
q.enq.Add(1)
|
q.enq.Add(1)
|
||||||
default:
|
default:
|
||||||
q.release(size)
|
q.release(size)
|
||||||
@@ -255,6 +256,15 @@ func (q *Queue) Submit(e *LogEntry) {
|
|||||||
q.mu.RUnlock()
|
q.mu.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cloneLogEntry(entry *LogEntry) *LogEntry {
|
||||||
|
clone := *entry
|
||||||
|
clone.RequestHeaders = append([]byte(nil), entry.RequestHeaders...)
|
||||||
|
clone.RequestBody = append([]byte(nil), entry.RequestBody...)
|
||||||
|
clone.ResponseHeaders = append([]byte(nil), entry.ResponseHeaders...)
|
||||||
|
clone.ResponseBody = append([]byte(nil), entry.ResponseBody...)
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
func (q *Queue) reserve(size int64) bool {
|
func (q *Queue) reserve(size int64) bool {
|
||||||
for {
|
for {
|
||||||
used := q.entries.Load()
|
used := q.entries.Load()
|
||||||
|
|||||||
@@ -314,6 +314,50 @@ func TestQueueReleasesSubmittedSizeAfterEntryMutation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQueueSubmitOwnsEntrySnapshot(t *testing.T) {
|
||||||
|
prepareStarted := make(chan struct{})
|
||||||
|
releasePrepare := make(chan struct{})
|
||||||
|
batch := &fakeBatch{}
|
||||||
|
backend := newQueueBackend(func(context.Context, string) (logger.Batch, error) {
|
||||||
|
close(prepareStarted)
|
||||||
|
<-releasePrepare
|
||||||
|
return batch, nil
|
||||||
|
})
|
||||||
|
entry := &logger.LogEntry{
|
||||||
|
RequestID: "original-id",
|
||||||
|
RequestHeaders: []byte("original-request-headers"),
|
||||||
|
RequestBody: []byte("original-request-body"),
|
||||||
|
ResponseHeaders: []byte("original-response-headers"),
|
||||||
|
ResponseBody: []byte("original-response-body"),
|
||||||
|
}
|
||||||
|
q := logger.NewQueueWithBackend(backend, 1, 1, 1, time.Hour)
|
||||||
|
q.Start(context.Background())
|
||||||
|
q.Submit(entry)
|
||||||
|
<-prepareStarted
|
||||||
|
|
||||||
|
entry.RequestID = "mutated-id"
|
||||||
|
entry.RequestHeaders[0] = 'X'
|
||||||
|
entry.RequestBody[0] = 'X'
|
||||||
|
entry.ResponseHeaders[0] = 'X'
|
||||||
|
entry.ResponseBody[0] = 'X'
|
||||||
|
close(releasePrepare)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
defer cancel()
|
||||||
|
if err := q.Stop(ctx); err != nil {
|
||||||
|
t.Fatalf("Stop: %v", err)
|
||||||
|
}
|
||||||
|
if len(batch.rows) != 1 {
|
||||||
|
t.Fatalf("written rows=%d want 1", len(batch.rows))
|
||||||
|
}
|
||||||
|
row := batch.rows[0]
|
||||||
|
if row[0] != "original-id" ||
|
||||||
|
row[5] != "original-request-headers" || row[6] != "original-request-body" ||
|
||||||
|
row[9] != "original-response-headers" || row[10] != "original-response-body" {
|
||||||
|
t.Fatalf("queued entry changed after Submit: %#v", row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestQueueCanceledStopEventuallyReleasesAllBudget(t *testing.T) {
|
func TestQueueCanceledStopEventuallyReleasesAllBudget(t *testing.T) {
|
||||||
entry := &logger.LogEntry{RequestID: "queued"}
|
entry := &logger.LogEntry{RequestID: "queued"}
|
||||||
q := logger.NewQueue(nil, 32, 32, 1, time.Hour, 32*logger.EstimatedBytes(entry))
|
q := logger.NewQueue(nil, 32, 32, 1, time.Hour, 32*logger.EstimatedBytes(entry))
|
||||||
|
|||||||
Reference in New Issue
Block a user