planleg

package
v0.40.6 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package planleg caches planner calls and caps how many a user can make.

A multi-day plan is one planner call per day, each ~10 s upstream, and the planner is edited a day at a time: re-planning after a change to day 3 should cost day 3 (and later days whose start SoC moved), not every day. Cache wraps a rivian.TripPlanner so that

  • a call with the same inputs inside 15 minutes is answered from Redis and is free, and
  • every call that does reach the upstream planner counts against the user's 60 per hour; the 61st is refused with a QuotaError.

Every planner is wrapped, not only the live one: a replay install's synthetic plan is a Valhalla route and a charger-archive scan, which a user can also run up. Simulated plans are deterministic for their inputs, so they cache like any other. Redis being down never blocks planning: the cache then misses and the quota allows.

Index

Constants

View Source
const (
	// TTL is how long a planned leg is served from cache.
	TTL = 15 * time.Minute
	// QuotaPerHour is the planner calls a user may send upstream per UTC hour.
	QuotaPerHour = 60
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

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

Cache is the Redis-backed leg cache and quota. A nil *Cache wraps nothing.

func New

func New(rdb *redis.Client, prefix string, log *slog.Logger) *Cache

New returns a Cache over rdb, or nil when there is no Redis. prefix keeps installs sharing a Redis out of each other's keys (RIVOLT_REDIS_KEY_PREFIX).

func (*Cache) Wrap

func (c *Cache) Wrap(inner rivian.TripPlanner, uid uuid.UUID) rivian.TripPlanner

Wrap returns inner behind the cache and the quota for uid. On a nil Cache it returns inner unchanged.

type QuotaError

type QuotaError struct {
	// RetryAfter is the time until the quota window resets.
	RetryAfter time.Duration
}

QuotaError is returned when a user is over their hourly planner quota.

func IsQuota

func IsQuota(err error) (*QuotaError, bool)

IsQuota reports whether err is a QuotaError and returns it.

func (*QuotaError) Error

func (e *QuotaError) Error() string

Jump to

Keyboard shortcuts

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