Documentation
¶
Index ¶
- type ConnectorInfo
- type DeliveryCallback
- type DeliveryResult
- func (r DeliveryResult) At(t time.Time) DeliveryResult
- func (r DeliveryResult) WithError(err error) DeliveryResult
- func (r DeliveryResult) WithOutcome(success bool, err error) DeliveryResult
- func (r DeliveryResult) WithStates(states map[string]string) DeliveryResult
- func (r DeliveryResult) WithSuccess() DeliveryResult
- type Dispatcher
- type DispatcherConfig
- type DispatcherOption
- type Instance
- type Notifier
- type Option
- type Overflow
- type Payload
- type PlanInfo
- type Request
- type Result
- type TargetInfo
- type TemplateEngine
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConnectorInfo ¶
type ConnectorInfo = sink.ConnectorInfo
ConnectorInfo carries resolved connector metadata for template rendering.
type DeliveryCallback ¶
type DeliveryCallback func(result DeliveryResult)
DeliveryCallback is invoked after each dispatch attempt to report delivery results back to the lifecycle processor for status tracking.
type DeliveryResult ¶
type DeliveryResult struct {
// ID is the canonical sink-status key for this delivery.
// It matches Request.ShortName() and is used to index
// per-sink state inside HibernateNotification.Status.SinkStatuses.
//
// Format: <sink>|<namespace>/<plan>|<cycle>|<operation>
ID string
NotificationRef types.NamespacedName
SinkName string
PlanNamespace string
PlanName string
CycleID string
Operation string
// Timestamp is when the dispatch completed.
Timestamp time.Time
// Success is true when the notification was delivered without error.
Success bool
// Error is the dispatch error, if any. Nil when Success is true.
Error error
// States carries sink-specific arbitrary key/value context emitted by sink
// delivery implementations (for example thread identifiers).
States map[string]string
}
DeliveryResult reports the outcome of a single notification dispatch.
func FromRequest ¶
func FromRequest(req Request) DeliveryResult
FromRequest pre-fills the identifier fields of a DeliveryResult from a Request.
func (DeliveryResult) At ¶
func (r DeliveryResult) At(t time.Time) DeliveryResult
At sets the completion timestamp.
func (DeliveryResult) WithError ¶
func (r DeliveryResult) WithError(err error) DeliveryResult
WithError marks the result as failed and records the error.
func (DeliveryResult) WithOutcome ¶
func (r DeliveryResult) WithOutcome(success bool, err error) DeliveryResult
WithOutcome sets both the success flag and the error in one call.
func (DeliveryResult) WithStates ¶
func (r DeliveryResult) WithStates(states map[string]string) DeliveryResult
WithStates attaches sink-specific state metadata.
func (DeliveryResult) WithSuccess ¶
func (r DeliveryResult) WithSuccess() DeliveryResult
WithSuccess marks the result as succeeded.
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
Dispatcher is a standalone controller-runtime Runnable that processes notification dispatch requests asynchronously. Hook closures submit Requests via Submit, which returns immediately (fire-and-forget). Requests are routed into per-stream FIFO slots managed by keyedworker. Each stream is processed by at most one worker at a time, guaranteeing deterministic ordering for that stream while preserving concurrency across independent streams.
The dispatcher:
- resolves sink credentials (Secret lookup via informer cache)
- renders the message via TemplateEngine (built-in defaults or custom ConfigMap templates)
- sends to the appropriate sink with a per-request timeout
- records Prometheus metrics (sent/errors/latency/drops)
Dispatch failures are logged and metered but never propagate errors to the caller.
func NewDispatcher ¶
func NewDispatcher(log logr.Logger, c client.Reader, registry *sink.Registry, cfg DispatcherConfig, opts ...DispatcherOption) *Dispatcher
NewDispatcher creates a new NotificationDispatcher. The client should be the cached reader (informer cache) for Secret lookups.
func (*Dispatcher) NeedLeaderElection ¶
func (d *Dispatcher) NeedLeaderElection() bool
NeedLeaderElection returns true — notifications should only fire from the leader.
func (*Dispatcher) Notifier ¶
func (d *Dispatcher) Notifier() Notifier
Notifier returns the Notifier interface backed by this Dispatcher. Consumers (plan processors, state handlers) should depend on this interface rather than on *Dispatcher directly.
func (*Dispatcher) Start ¶
func (d *Dispatcher) Start(ctx context.Context) error
Start implements manager.Runnable. It wires keyed per-stream workers and blocks until ctx is cancelled. During shutdown, new submissions are rejected and active stream workers are given a bounded time window to drain pending per-stream items before Start returns.
func (*Dispatcher) Submit ¶
func (d *Dispatcher) Submit(req Request)
Submit enqueues a dispatch request. It never blocks the caller. Requests are routed into per-stream FIFO slots; if a per-stream buffer is full, the request is dropped by the slot and counted in NotificationDropTotal. After shutdown begins (d.done closed), requests are discarded with a metric.
type DispatcherConfig ¶
type DispatcherConfig struct {
// ChannelSize is the buffered channel capacity for dispatch requests.
// Default: 256.
ChannelSize int
// DispatchTimeout is the per-sink HTTP call timeout.
// Default: 5s.
DispatchTimeout time.Duration
// WorkerIdleTTL is how long an idle per-stream worker stays alive before exiting.
// Default: 30m.
WorkerIdleTTL time.Duration
}
DispatcherConfig holds tuning knobs for the notification Dispatcher. Zero values are replaced with sensible defaults.
type DispatcherOption ¶
type DispatcherOption func(*Dispatcher)
DispatcherOption configures an optional dependency of a Dispatcher.
type Instance ¶
type Instance struct {
// Notifier is the submit-only interface distributed to plan processors and
// state handlers — analogous to status.Updater.
Notifier Notifier
// Runnable is the controller-runtime Runnable that must be registered via
// mgr.Add(). It owns the dispatch goroutine pool and channel lifecycle.
Runnable manager.Runnable
}
Instance represents a notification subsystem instance with its Notifier interface and Runnable dispatcher.
func New ¶
New constructs the notification subsystem instance: sink registry, template engine, and dispatcher. It registers all built-in sink implementations (Slack, Telegram, fake) using a shared retryable HTTP client unless DisableDefaultSinks is specified, builds a TemplateEngine backed by the controller-runtime client, and returns an Instance whose Notifier can be distributed to processors.
This is the single public entry point that hides all notification internals from the setup/wiring layer.
type Notifier ¶
type Notifier interface {
Submit(req Request)
}
Notifier is the write-facing interface exposed to consumers (state handlers, processors). It intentionally hides all dispatcher and pool internals, mirroring the pattern used by status.Updater.
type Option ¶
type Option func(*config)
Option configures the notification subsystem constructed by New.
func DisableDefaultSinks ¶
func DisableDefaultSinks() Option
DisableDefaultSinks disables the default built-in sink registrations (Slack, Telegram, fake). Combine with WithSink to construct a fully-controlled registry for testing.
func WithDeliveryCallback ¶
func WithDeliveryCallback(cb DeliveryCallback) Option
WithDeliveryCallback registers a callback invoked after each dispatch attempt. Used by the notification lifecycle processor to track per-sink delivery status.
func WithDispatcherConfig ¶
func WithDispatcherConfig(cfg DispatcherConfig) Option
WithDispatcherConfig overrides the default dispatcher configuration.
type Overflow ¶
type Overflow[T any] struct { // contains filtered or unexported fields }
Overflow is a concurrency-safe, unbounded spillover queue.
It is designed as a companion to a bounded channel: when the channel is full, callers Append items here instead of blocking. A background drainer moves items from the Overflow back into the channel as capacity becomes available.
All methods are safe for concurrent use. The Consume method uses a take-and-return pattern to process items outside the lock without positional-mismatch races.
func (*Overflow[T]) Append ¶
func (o *Overflow[T]) Append(item T)
Append adds an item to the back of the overflow queue.
func (*Overflow[T]) Consume ¶
Consume atomically takes ownership of items, processes them outside the lock, and prepends any unconsumed remainder back under the lock.
fn is called for each item in order. If fn returns true the item is consumed and discarded. If fn returns false processing stops; that item and all remaining items are returned to the front of the queue (preserving order for the next call).
Because items are extracted before fn runs, concurrent Append calls do not interfere with the consumed prefix — eliminating the positional-mismatch race that would occur with a snapshot-then-trim approach.
func (*Overflow[T]) Range ¶
func (o *Overflow[T]) Range(fn func(T))
Range calls fn for each item while holding the lock. Use for short, non-blocking callbacks only; for potentially blocking work prefer Consume.
type Request ¶
type Request struct {
// Payload carries the notification event data.
Payload Payload
// SinkName is the human-readable sink identifier (for logging).
SinkName string
// SinkType is the sink provider type (e.g., "slack", "telegram", "webhook").
SinkType string
// SecretRef references the Secret containing sink config.
// If Key is empty, the dispatcher uses a default key.
SecretRef hibernatorv1alpha1.ObjectKeyReference
// TemplateRef optionally references a ConfigMap key for custom templates.
// Nil means use the default template.
TemplateRef *hibernatorv1alpha1.ObjectKeyReference
// NotificationRef identifies the HibernateNotification that owns this request.
// Used by the delivery callback to update per-sink status.
NotificationRef types.NamespacedName
}
Request represents a single notification request submitted by a hook closure. It contains all data needed by the dispatcher to resolve credentials, render the message, and send it to the sink.
func (Request) ShortName ¶
ShortName returns the canonical sink-status key for this request.
Format: <sink>|<namespace>/<plan>|<cycle>|<operation>
This key is used to index per-sink delivery state inside HibernateNotification.Status.SinkStatuses.
func (Request) String ¶
String returns a fully-qualified string that uniquely identifies this request across the entire cluster. It includes the notification reference so that two requests for the same sink/plan/cycle but different HibernateNotification objects do not collide.
Format: <notification>|<sink>|<namespace>/<plan>|<cycle>|<operation>
type Result ¶
type Result = sink.SendResult
Result carries the outcome of a sink Send operation, including any sink-specific metadata.
type TargetInfo ¶
type TargetInfo = sink.TargetInfo
TargetInfo holds execution state for a single target.
type TemplateEngine ¶
type TemplateEngine struct {
// contains filtered or unexported fields
}
TemplateEngine renders notification messages from Go templates. It implements the sink.Renderer interface so that sinks can request on-demand rendering of their built-in or custom templates.
Default (embedded) templates are parsed once and cached by sink type — they never change at runtime. Custom (user-provided) templates are re-parsed on every call so content changes take effect immediately.
func NewTemplateEngine ¶
func NewTemplateEngine(log logr.Logger) *TemplateEngine
NewTemplateEngine creates a new TemplateEngine. Default templates are lazily cached on first Render call for each sink type.
func (*TemplateEngine) Render ¶
func (e *TemplateEngine) Render(ctx context.Context, payload Payload, opts ...sink.RenderOption) string
Render implements sink.Renderer. It resolves the template for the given payload (default for the sink type, or a custom override via RenderOption), executes it against the Payload, and returns the rendered message. On any error, a plain-text fallback is returned.