timers

package
v0.2.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

pkg/controller/timers

Single-goroutine *time.Timer wrapper that papers over Go's well-known timer footguns.

Overview

SafeTimer provides safe Stop / Reset operations and exposes the channel as Chan() <-chan time.Time (returning nil when no timer is active so it blocks forever in a select). It exists because plain time.Timer.Reset after Stop returning false can leak a stale tick into the next cycle, and every component that uses timers in its event loop would otherwise re-implement the drain dance.

It must only be used from a single goroutine — there is no internal synchronisation.

Quick Start

import "gitlab.com/haproxy-haptic/haptic/pkg/controller/timers"

var t timers.SafeTimer

for {
    select {
    case event := <-eventChan:
        // Trailing-edge debounce: every event resets the countdown.
        t.Reset(5 * time.Second)
        process(event)

    case <-t.Chan():
        t.Fired() // MUST be called after receiving — clears the internal
                  // reference so Chan() goes back to nil until the next Reset.
        flush()

    case <-ctx.Done():
        t.Stop()
        return
    }
}

Fired() is easy to forget. Without it, t.timer != nil keeps reading as true even after the timer's channel was drained, so a stale reference lingers until the next Reset or Stop.

Reset implements trailing-edge debouncing — pkg/controller/configchange is the only current production user.

See Also

License

Apache-2.0 — see root LICENSE.

Documentation

Overview

Package timers provides safe timer management for event-driven controller components.

SafeTimer wraps *time.Timer with safe stop/drain/reset operations that avoid the common pitfalls of Go timer usage (leaked channels, double-drain races). It is designed for single-goroutine use within select loops.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SafeTimer

type SafeTimer struct {
	// contains filtered or unexported fields
}

SafeTimer wraps *time.Timer with safe stop, drain, reset, and channel-get operations. It must only be used from a single goroutine (no internal synchronization).

func (*SafeTimer) Chan

func (t *SafeTimer) Chan() <-chan time.Time

Chan returns the timer's channel, or nil if no timer is active. A nil channel blocks forever in a select, which is the desired behavior when there is no active timer.

func (*SafeTimer) Fired

func (t *SafeTimer) Fired()

Fired should be called when the timer's channel is read in a select case. It clears the internal reference so a new timer can be started.

func (*SafeTimer) Reset

func (t *SafeTimer) Reset(d time.Duration)

Reset stops any existing timer and starts a new one with the given duration. This implements trailing-edge debounce: every call resets the countdown.

func (*SafeTimer) Stop

func (t *SafeTimer) Stop()

Stop stops the timer if running, drains the channel, and clears the reference.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL