Files
logwisp/internal/sink/sink.go
T
lixen 4af072f4e5
Test / test (push) Canceled after 0s
Test / e2e (push) Canceled after 0s
v0.25.0 netacl and fixes
2026-10-04 23:43:52 -04:00

80 lines
2.0 KiB
Go

package sink
import (
"context"
"time"
"github.com/lixenwraith/logwisp/internal/core"
)
// Sink represents an output data stream.
type Sink interface {
// Capabilities returns a slice of supported Source capabilities
Capabilities() []core.Capability
// Input returns the channel for sending transport events to this sink.
Input() chan<- core.TransportEvent
// Start begins processing transport events.
Start(ctx context.Context) error
// Stop gracefully shuts down the sink.
Stop()
// GetStats returns sink statistics.
GetStats() SinkStats
}
// SinkStats contains statistics about a sink.
type SinkStats struct {
ID string
Type string
TotalProcessed uint64
ActiveConnections int64
StartTime time.Time
LastProcessed time.Time
Details map[string]any
}
// FlushBound is how long a network sink's Stop gives what is queued to reach
// its clients or its downstream: its write or request timeout, at most
// core.SinkFlushTimeout, which a reload also waits out for a stalled peer.
func FlushBound(writeTimeout time.Duration) time.Duration {
if writeTimeout > 0 && writeTimeout < core.SinkFlushTimeout {
return writeTimeout
}
return core.SinkFlushTimeout
}
// FlushContext is ctx ending FlushBound(timeout) after done closes: a sink
// that dials runs its loop under it, so Stop leaves its queue that long.
func FlushContext(ctx context.Context, done <-chan struct{}, timeout time.Duration) (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(ctx)
go func() {
select {
case <-done:
select {
case <-time.After(FlushBound(timeout)):
case <-ctx.Done():
}
case <-ctx.Done():
}
cancel()
}()
return ctx, cancel
}
// Drain takes the payloads queued in input without waiting: a network sink's
// last events, which each client then writes on its own.
func Drain(input <-chan core.TransportEvent) [][]byte {
var tail [][]byte
for {
select {
case event := <-input:
tail = append(tail, event.Payload)
default:
return tail
}
}
}