Documentation
¶
Overview ¶
Package clock provides narrow time capabilities backed by the standard library and deterministic implementations for tests.
Wall-clock timestamps and monotonic elapsed time are deliberately distinct. A time.Time returned by System.Now retains the process-local monotonic reading supplied by time.Now. Serialization removes that reading, so persisted values must never be used as a substitute for monotonic elapsed measurement.
Index ¶
- Constants
- Variables
- type Callback
- type CallbackClock
- type Clock
- type ElapsedClock
- type FullClock
- type Kind
- type Observation
- type ObserveOption
- type Observer
- type ObserverFunc
- type Outcome
- type Sleeper
- type System
- func (System) AfterFunc(d time.Duration, fn func()) (Callback, error)
- func (System) Measure() func() time.Duration
- func (System) NewTicker(d time.Duration) (Ticker, error)
- func (System) NewTimer(d time.Duration) (Timer, error)
- func (System) Now() time.Time
- func (System) Since(start time.Time) time.Duration
- func (System) Sleep(ctx context.Context, d time.Duration) error
- type Ticker
- type TickerFactory
- type Timer
- type TimerFactory
Examples ¶
Constants ¶
const ( // MaxObservationTags bounds labels attached to one observation. MaxObservationTags = 16 // MaxObservationTagBytes bounds each tag key and value. MaxObservationTagBytes = 64 )
Variables ¶
var ( // ErrInvalidDuration reports a duration that is not valid for an operation. ErrInvalidDuration = errors.New("clock: invalid duration") // ErrInvalidCallback reports a nil callback function. ErrInvalidCallback = errors.New("clock: invalid callback") // ErrOverflow reports a time operation outside time.Duration's range. ErrOverflow = errors.New("clock: duration overflow") )
var ( // ErrInvalidClock reports a nil clock passed to Observe. ErrInvalidClock = errors.New("clock: invalid clock") // ErrInvalidObserver reports a nil observer passed to Observe. ErrInvalidObserver = errors.New("clock: invalid observer") // ErrObservationTags reports tags outside the documented bounds. ErrObservationTags = errors.New("clock: invalid observation tags") )
Functions ¶
This section is empty.
Types ¶
type Callback ¶
Callback is an owned timer callback.
Stop reports whether it prevented the callback from starting. It does not wait for an already-started callback to finish.
type CallbackClock ¶
CallbackClock creates owned timer callbacks.
type Clock ¶
Clock obtains the current wall-clock time.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/faustbrian/go-clock/manual"
)
func main() {
start := time.Date(2026, 1, 2, 3, 4, 5, 0, time.UTC)
manualClock, err := manual.New(start)
if err != nil {
panic(err)
}
timer, err := manualClock.NewTimer(time.Minute)
if err != nil {
panic(err)
}
waiter, err := manualClock.Advance(time.Minute)
if err != nil {
panic(err)
}
if _, err := waiter.Wait(context.Background()); err != nil {
panic(err)
}
fmt.Println((<-timer.C()).Format(time.RFC3339))
}
Output: 2026-01-02T03:05:05Z
type ElapsedClock ¶
ElapsedClock measures process-local elapsed time. Since accepts a time.Time with standard-library monotonic semantics. Measure returns a closure tied to the implementation's monotonic source and is the safe choice across explicit manual wall-clock jumps.
type FullClock ¶
type FullClock interface {
Clock
ElapsedClock
Sleeper
TimerFactory
TickerFactory
CallbackClock
}
FullClock is a convenience composition for consumers that genuinely need every capability. Consumers should normally accept a narrower interface.
func Observe ¶
func Observe(base FullClock, observer Observer, options ...ObserveOption) (FullClock, error)
Observe decorates a FullClock with bounded synchronous lifecycle hooks. It starts no goroutine and owns no exporter or global registry.
Example ¶
package main
import (
"fmt"
"time"
clock "github.com/faustbrian/go-clock"
)
func main() {
observed, err := clock.Observe(clock.System{}, clock.ObserverFunc(func(observation clock.Observation) {
fmt.Println(observation.Kind, observation.Outcome)
}))
if err != nil {
panic(err)
}
timer, err := observed.NewTimer(time.Hour)
if err != nil {
panic(err)
}
timer.Stop()
}
Output: timer created timer stopped
type Kind ¶
type Kind string
Kind identifies an observed time resource.
const ( // KindSleep identifies a context-aware sleep. KindSleep Kind = "sleep" // KindTimer identifies a one-shot channel timer. KindTimer Kind = "timer" // KindTicker identifies a periodic channel ticker. KindTicker Kind = "ticker" // KindCallback identifies an AfterFunc callback. KindCallback Kind = "callback" )
type Observation ¶
type Observation struct {
Kind Kind
Outcome Outcome
Requested time.Duration
Elapsed time.Duration
Tags map[string]string
}
Observation contains bounded lifecycle metadata. It never contains callback functions, panic payloads, timestamps, contexts, or other sensitive values.
type ObserveOption ¶
type ObserveOption func(*observeConfig) error
ObserveOption configures an observed clock.
func WithTags ¶
func WithTags(tags map[string]string) ObserveOption
WithTags attaches a bounded defensive copy of tags to every observation.
type Observer ¶
type Observer interface {
Observe(Observation)
}
Observer consumes lifecycle metadata. Implementations must return promptly; panics are isolated from clock behavior.
type ObserverFunc ¶
type ObserverFunc func(Observation)
ObserverFunc adapts a function to Observer.
func (ObserverFunc) Observe ¶
func (function ObserverFunc) Observe(observation Observation)
Observe calls function with observation.
type Outcome ¶
type Outcome string
Outcome identifies an observed lifecycle transition.
const ( // OutcomeCreated reports successful resource creation. OutcomeCreated Outcome = "created" // OutcomeCompleted reports successful synchronous completion. OutcomeCompleted Outcome = "completed" // OutcomeCanceled reports context cancellation. OutcomeCanceled Outcome = "canceled" // OutcomeStopped reports a successful active-to-stopped transition. OutcomeStopped Outcome = "stopped" // OutcomeInactive reports an operation on an inactive resource. OutcomeInactive Outcome = "inactive" // OutcomeReset reports successful rescheduling. OutcomeReset Outcome = "reset" // OutcomeFired reports callback execution. OutcomeFired Outcome = "fired" // OutcomePanicked reports a callback panic without its payload. OutcomePanicked Outcome = "panicked" // OutcomeRejected reports validation or resource rejection. OutcomeRejected Outcome = "rejected" )
type System ¶
type System struct{}
System delegates time operations to the Go standard library.
Its zero value is ready for concurrent use and owns no background resources.
Example ¶
package main
import (
"fmt"
clock "github.com/faustbrian/go-clock"
)
func main() {
var timestamps clock.Clock = clock.System{}
_ = timestamps.Now()
fmt.Println("system clock ready")
}
Output: system clock ready
func (System) Measure ¶
Measure captures the current standard-library monotonic reading and returns a closure that reports elapsed time from it.
type Ticker ¶
Ticker is an owned periodic time event.
The owner must call Stop. Ticks may be dropped for a slow receiver, matching time.Ticker. Reset returns ErrInvalidDuration for a non-positive duration instead of exposing the standard library's panic across an interface seam.
type TickerFactory ¶
TickerFactory creates owned periodic tickers.
type Timer ¶
Timer is an owned, one-shot time event.
Stop and Reset have the same return-value semantics as time.Timer. The owner must stop a timer it no longer needs. As of Go 1.26, timer channels are synchronous and an unbuffered receive after Stop reports true cannot observe a stale value from the prior configuration.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package clocktest contains deterministic testing helpers for clock.
|
Package clocktest contains deterministic testing helpers for clock. |
|
Package manual provides deterministic fixed and manually advanced clocks.
|
Package manual provides deterministic fixed and manually advanced clocks. |