2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2018-04-04 03:46:07 +00:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2018-04-22 20:52:48 +00:00
|
|
|
// Type implements the logic to fetch certain types of data.
|
2022-10-21 19:58:06 +00:00
|
|
|
//
|
2022-07-05 21:57:15 +00:00
|
|
|
//go:generate mockery --name Type --inpackage
|
2018-04-04 03:46:07 +00:00
|
|
|
type Type interface {
|
|
|
|
// Fetch fetches a single unique item.
|
|
|
|
//
|
2019-01-10 12:46:11 +00:00
|
|
|
// The FetchOptions contain the index and timeouts for blocking queries. The
|
|
|
|
// MinIndex value on the Request itself should NOT be used as the blocking
|
|
|
|
// index since a request may be reused multiple times as part of Refresh
|
|
|
|
// behavior.
|
2018-04-04 03:46:07 +00:00
|
|
|
//
|
2019-01-10 12:46:11 +00:00
|
|
|
// The return value is a FetchResult which contains information about the
|
|
|
|
// fetch. If an error is given, the FetchResult is ignored. The cache does not
|
|
|
|
// support backends that return partial values. Optional State can be added to
|
|
|
|
// the FetchResult which will be stored with the cache entry and provided to
|
|
|
|
// the next Fetch call but will not be returned to clients. This allows types
|
|
|
|
// to add additional bookkeeping data per cache entry that will still be aged
|
|
|
|
// out along with the entry's TTL.
|
2018-04-16 10:06:08 +00:00
|
|
|
//
|
2019-01-10 12:46:11 +00:00
|
|
|
// On timeout, FetchResult can behave one of two ways. First, it can return
|
|
|
|
// the last known value. This is the default behavior of blocking RPC calls in
|
|
|
|
// Consul so this allows cache types to be implemented with no extra logic.
|
|
|
|
// Second, FetchResult can return an unset value and index. In this case, the
|
|
|
|
// cache will reuse the last value automatically. If an unset Value is
|
2019-01-22 17:19:36 +00:00
|
|
|
// returned, the State field will still be updated which allows maintaining
|
|
|
|
// metadata even when there is no result.
|
2018-04-04 03:46:07 +00:00
|
|
|
Fetch(FetchOptions, Request) (FetchResult, error)
|
2018-09-06 10:34:28 +00:00
|
|
|
|
2020-04-14 22:29:30 +00:00
|
|
|
// RegisterOptions are used when the type is registered to configure the
|
|
|
|
// behaviour of cache entries for this type.
|
|
|
|
RegisterOptions() RegisterOptions
|
2018-04-04 03:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FetchOptions are various settable options when a Fetch is called.
|
|
|
|
type FetchOptions struct {
|
|
|
|
// MinIndex is the minimum index to be used for blocking queries.
|
|
|
|
// If blocking queries aren't supported for data being returned,
|
|
|
|
// this value can be ignored.
|
|
|
|
MinIndex uint64
|
|
|
|
|
|
|
|
// Timeout is the maximum time for the query. This must be implemented
|
|
|
|
// in the Fetch itself.
|
|
|
|
Timeout time.Duration
|
2019-01-10 12:46:11 +00:00
|
|
|
|
|
|
|
// LastResult is the result from the last successful Fetch and represents the
|
|
|
|
// value currently stored in the cache at the time Fetch is invoked. It will
|
|
|
|
// be nil on first call where there is no current cache value. There may have
|
|
|
|
// been other Fetch attempts that resulted in an error in the mean time. These
|
|
|
|
// are not explicitly represented currently. We could add that if needed this
|
|
|
|
// was just simpler for now.
|
|
|
|
//
|
|
|
|
// The FetchResult read-only! It is constructed per Fetch call so modifying
|
|
|
|
// the struct directly (e.g. changing it's Index of Value field) will have no
|
|
|
|
// effect, however the Value and State fields may be pointers to the actual
|
|
|
|
// values stored in the cache entry. It is thread-unsafe to modify the Value
|
|
|
|
// or State via pointers since readers may be concurrently inspecting those
|
|
|
|
// values under the entry lock (although we guarantee only one Fetch call per
|
|
|
|
// entry) and modifying them even if the index doesn't change or the Fetch
|
|
|
|
// eventually errors will likely break logical invariants in the cache too!
|
|
|
|
LastResult *FetchResult
|
2018-04-04 03:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FetchResult is the result of a Type Fetch operation and contains the
|
|
|
|
// data along with metadata gathered from that operation.
|
|
|
|
type FetchResult struct {
|
|
|
|
// Value is the result of the fetch.
|
|
|
|
Value interface{}
|
|
|
|
|
2019-01-10 12:46:11 +00:00
|
|
|
// State is opaque data stored in the cache but not returned to clients. It
|
|
|
|
// can be used by Types to maintain any bookkeeping they need between fetches
|
|
|
|
// (using FetchOptions.LastResult) in a way that gets automatically cleaned up
|
|
|
|
// by TTL expiry etc.
|
|
|
|
State interface{}
|
|
|
|
|
2018-04-04 03:46:07 +00:00
|
|
|
// Index is the corresponding index value for this data.
|
|
|
|
Index uint64
|
2020-07-06 17:26:56 +00:00
|
|
|
|
|
|
|
// NotModified indicates that the Value has not changed since LastResult, and
|
|
|
|
// the LastResult value should be used instead of Value.
|
|
|
|
NotModified bool
|
2018-04-04 03:46:07 +00:00
|
|
|
}
|