timeout

package
v0.1.1-rc1 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MapTickFired

func MapTickFired[Out actor.Message](targetRef actor.TellOnlyRef[Out],
	mapFn func(TickFiredMsg) Out) actor.TellOnlyRef[*TickFiredMsg]

MapTickFired creates a transformed TellOnlyRef that converts recurring- tick fire messages into a target actor's message type. It mirrors MapTimeoutExpired for the recurring-tick scheduler:

tickRef := timeout.MapTickFired(
    roundsActorRef,
    func(fired timeout.TickFiredMsg) rounds.ActorMsg {
        return &rounds.TickFired{ID: fired.ID}
    },
)

timeoutActorRef.Tell(ctx, &timeout.ScheduleRecurringTickRequest{
    ID:       compositeID,
    Interval: m.Interval,
    Callback: tickRef,
})

func MapTimeoutExpired

func MapTimeoutExpired[Out actor.Message](targetRef actor.TellOnlyRef[Out],
	mapFn func(ExpiredMsg) Out) actor.TellOnlyRef[*ExpiredMsg]

MapTimeoutExpired creates a transformed TellOnlyRef that converts timeout expiry messages into a target actor's message type. This helper simplifies integrating the timeout actor with other actors by automatically transforming ExpiredMsg into the appropriate message type.

Example usage:

// Transform timeout expiry into a rounds actor message.
callbackRef := timeout.MapTimeoutExpired(
    roundsActorRef,
    func(expired timeout.ExpiredMsg) rounds.ActorMsg {
        return &rounds.TimeoutExpired{
  	      ID: expired.ID,
  	}
    },
)

// Send schedule request to timeout actor.
timeoutActorRef.Tell(ctx, &timeout.ScheduleTimeoutRequest{
	ID:       timeout.ID(m.RoundID),
	Duration: m.Duration,
	Callback: callbackRef,
})

Types

type AckResponse

type AckResponse struct {
	actor.BaseMessage

	// Success indicates whether the operation succeeded.
	Success bool

	// Error contains an error message if Success is false.
	Error string
}

AckResponse acknowledges a schedule or cancel request.

func (*AckResponse) MessageType

func (m *AckResponse) MessageType() string

MessageType returns the type of this message.

type Actor

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

Actor is the timeout scheduling actor. It manages one-shot timers and recurring tickers, sending notifications when they fire.

All state lives only inside the actor's Receive goroutine. Clock callbacks Tell self with an internalTimerFired / internalTickFired message and the real state mutation happens when that message reaches Receive — there is no cross-goroutine map access, so no mutex.

Recurring ticks are implemented as a chain of one-shot timers: each fire delivers TickFiredMsg to the user callback and re-arms via AfterFunc. This gives "fixed-delay" semantics (the next tick is scheduled at handler-finish + interval) and avoids the burst-of-ticks catch-up behaviour of time.Ticker when a consumer is slow.

func NewActor

func NewActor() *Actor

NewActor creates a new timeout actor backed by the real wall clock. The returned actor must be wired to its mailbox via Start before any schedule request is delivered.

func NewActorWithClock

func NewActorWithClock(clock Clock) *Actor

NewActorWithClock creates a new timeout actor that uses the supplied clock. Tests use this constructor with a fake clock to drive scheduling deterministically.

func (*Actor) Receive

func (a *Actor) Receive(ctx context.Context, msg Msg) fn.Result[Resp]

Receive processes incoming messages.

func (*Actor) Start

func (a *Actor) Start(self actor.TellOnlyRef[Msg])

Start attaches the actor's self-reference. Production callers obtain this ref from actor.RegisterWithSystem and pass it here so that clock callbacks can Tell internal fire messages back into the actor's own mailbox. Tests that drive the actor directly (without an ActorSystem) inject a synchronous self-ref via newSyncSelfRef.

Start must be called before any ScheduleTimeoutRequest or ScheduleRecurringTickRequest is delivered. It is safe to call once only — subsequent calls overwrite the self-ref.

type CancelTimeoutRequest

type CancelTimeoutRequest struct {
	actor.BaseMessage

	// ID is the unique identifier of the timeout to cancel.
	ID ID
}

CancelTimeoutRequest requests the timeout actor to cancel a pending timeout.

func (*CancelTimeoutRequest) MessageType

func (m *CancelTimeoutRequest) MessageType() string

MessageType returns the type of this message.

type Clock

type Clock interface {
	// Now returns the current time.
	Now() time.Time

	// AfterFunc schedules f to run after d. The returned Stoppable can
	// be used to cancel the pending call.
	AfterFunc(d time.Duration, f func()) Stoppable
}

Clock abstracts wall-clock time so tests can deterministically advance it. Production callers receive a RealClock implicitly via NewActor; tests instead pass a fake clock through NewActorWithClock and drive time forward step-by-step.

AfterFunc is the only scheduling primitive: recurring ticks are built on top of it as a chain of one-shots that re-arm from inside the actor's Receive method, so there is no need for a separate Ticker abstraction.

type ExpiredMsg

type ExpiredMsg struct {
	actor.BaseMessage

	// ID is the unique identifier of the timeout that expired.
	ID ID
}

ExpiredMsg is sent back to the callback when a timeout expires. This message is also a valid Msg so it can be received by the rounds actor.

func (*ExpiredMsg) MessageType

func (m *ExpiredMsg) MessageType() string

MessageType returns the type of this message.

type ID

type ID string

ID is a unique identifier for a scheduled timeout. This is intentionally generic so that it can be used by any component that needs timeout scheduling (e.g., rounds, sessions, etc.).

type Msg

type Msg interface {
	actor.Message
	// contains filtered or unexported methods
}

Msg is the sealed interface for messages that can be sent to the TimeoutActor.

type RealClock

type RealClock struct{}

RealClock is the production Clock implementation. It delegates to the standard library time package.

func (RealClock) AfterFunc

func (RealClock) AfterFunc(d time.Duration, f func()) Stoppable

AfterFunc returns a *time.Timer wrapped as a Stoppable.

func (RealClock) Now

func (RealClock) Now() time.Time

Now returns time.Now().

type Resp

type Resp interface {
	actor.Message
	// contains filtered or unexported methods
}

Resp is the sealed interface for responses from the TimeoutActor.

type ScheduleRecurringTickRequest

type ScheduleRecurringTickRequest struct {
	actor.BaseMessage

	// ID is the unique identifier for this recurring tick. It shares
	// the namespace with one-shot timeout IDs; CancelTimeoutRequest
	// works on either.
	ID ID

	// Interval is the cadence at which TickFiredMsg is delivered.
	Interval time.Duration

	// Callback receives a *TickFiredMsg on each tick.
	Callback actor.TellOnlyRef[*TickFiredMsg]
}

ScheduleRecurringTickRequest schedules a recurring tick that fires *TickFiredMsg to Callback at every Interval, until cancelled. Cancel uses the existing CancelTimeoutRequest keyed by ID. The first fire is at Interval (not immediate). Re-scheduling with the same ID stops the previous ticker.

func (*ScheduleRecurringTickRequest) MessageType

func (m *ScheduleRecurringTickRequest) MessageType() string

MessageType returns the type of this message.

type ScheduleTimeoutRequest

type ScheduleTimeoutRequest struct {
	actor.BaseMessage

	// ID is the unique identifier for this timeout.
	ID ID

	// Duration is how long to wait before the timeout expires.
	Duration time.Duration

	// The timeout actor will send *ExpiredMsg to this reference.
	Callback actor.TellOnlyRef[*ExpiredMsg]
}

ScheduleTimeoutRequest requests the timeout actor to schedule a timeout. When the timeout expires, an ExpiredMsg will be sent to the Callback.

func (*ScheduleTimeoutRequest) MessageType

func (m *ScheduleTimeoutRequest) MessageType() string

MessageType returns the type of this message.

type Stoppable

type Stoppable interface {
	// Stop prevents the timer from firing. Returns true if the call
	// stops the timer, false if the timer has already fired or been
	// stopped.
	Stop() bool
}

Stoppable is a one-shot timer handle. *time.Timer satisfies this interface directly.

type TickFiredMsg

type TickFiredMsg struct {
	actor.BaseMessage

	// ID is the recurring tick that fired.
	ID ID

	// FiredAt is the wall-clock time the tick was generated by the
	// scheduler. Under a fake clock this is the test's logical time.
	FiredAt time.Time
}

TickFiredMsg is delivered to a recurring callback on each tick.

func (*TickFiredMsg) MessageType

func (m *TickFiredMsg) MessageType() string

MessageType returns the type of this message.

Jump to

Keyboard shortcuts

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