VictoriaMetrics/lib/contextutil/stop_chan_context.go
Aliaksandr Valialkin f5dfe1cacd
lib/logstorage: properly return surrounding logs outside the selected time range by stream_context pipe
Previously only logs inside the selected time range could be returned by stream_context pipe.
For example, the following query could return up to 10 surrounding logs only for the last 5 minutes,
while most users expect this query should return up to 10 surrounding logs without restrictions on the time range.

    _time:5m panic | stream_context before 10

This enables the ability to implement stream context feature at VictoriaLogs web UI: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7063 .

Reduce memory usage when returning stream context over big log streams with millions of entries.
The new logic scans over all the log messages for the selected log stream, while keeping in memory only
the given number of surrounding logs. Previously all the logs for the given log stream on the selected time range
were loaded in memory before selecting the needed surrounding logs.
This should help https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6730 .

Reduce the scan performance for big log streams by fetching only the requested fields. For example, the following
query should be executed much faster than before if logs contain many fields other than _stream, _msg and _time:

    panic | stream_context after 30 | fields _stream, _msg, _time
2024-09-26 17:04:39 +02:00

47 lines
1 KiB
Go

package contextutil
import (
"context"
"time"
)
// NewStopChanContext returns new context for the given stopCh, together with cancel function.
//
// The returned context is canceled on the following events:
//
// - when stopCh is closed
// - when the returned CancelFunc is called
//
// The caller must call the returned CancelFunc when the context is no longer needed.
func NewStopChanContext(stopCh <-chan struct{}) (context.Context, context.CancelFunc) {
ctx := &stopChanContext{
stopCh: stopCh,
}
return context.WithCancel(ctx)
}
// stopChanContext implements context.Context for stopCh passed to newStopChanContext.
type stopChanContext struct {
stopCh <-chan struct{}
}
func (ctx *stopChanContext) Deadline() (time.Time, bool) {
return time.Time{}, false
}
func (ctx *stopChanContext) Done() <-chan struct{} {
return ctx.stopCh
}
func (ctx *stopChanContext) Err() error {
select {
case <-ctx.stopCh:
return context.Canceled
default:
return nil
}
}
func (ctx *stopChanContext) Value(key any) any {
return nil
}