Documentation ¶
Overview ¶
Package store implements some additional atomic value storage on top of sync/atomic. In particular, this means transparent caching of arbitrary values.
Index ¶
Constants ¶
const ( // CachePeriodForever is a special value that means a cache never expires CachePeriodForever CachePeriod = 0 // CachePeriodForeverValue is the string value indicating that a cache never expires CachePeriodForeverValue string = "forever" // CachePeriodNever is a special value indicating something must never be cached. // Any negative value for CachePeriod will be interpreted as this value. CachePeriodNever CachePeriod = -1 // CachePeriodNeverValue is the string value indicating that something should not be cached CachePeriodNeverValue string = "never" )
Variables ¶
var ( ErrorInvalidMaxSize = errors.New("The maxSize of a pool must be positive") ErrorInvalidInitialSize = errors.New("The initialSize of a pool cannot be larger than maxSize") ErrorNewRequired = errors.New("A new function is required") ErrorPoolClosed = errors.New("The pool is already closed") )
var (
NegativeCachePeriod = errors.New("The cache period must be positive")
)
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is an on-demand cache for an arbitrary value. This type implements the Value interface.
Cache management is done inline with the Load() method. No other goroutine is necessary to monitor instances of this type.
func NewCache ¶
func NewCache(source Value, period CachePeriod) (*Cache, error)
NewCache constructs a new Cache that uses the given source. The period parameter must be positive, so special values such as CachePeriodForever are not supported by this function.
To dynamically create a Value based on a CachePeriod, use NewValue() instead.
func (*Cache) Load ¶
Load will return the currently cached value if there is one and it hasn't expired. If the cache has no value yet or if the existing value has expired, this method consults the source Value to update its cache and returns the new value.
In the event that a cache has an expired value and cannot get a fresh one from the source, this method uses the old cache value and sets a new expiry time. This allows the application to continue using the old value in the event of intermediate I/O problems. No error is returned in that case.
type CachePeriod ¶
CachePeriod is a custom type which describes the amount of time before a cached value is considered to have been expired. This type has several reserved values that govern caching behavior.
func (CachePeriod) MarshalJSON ¶
func (c CachePeriod) MarshalJSON() (data []byte, err error)
MarshalJSON provides the custom JSON format for a cache period.
func (CachePeriod) Next ¶
func (c CachePeriod) Next(base time.Time) time.Time
Next returns time after a given, base time when the period has elapsed
func (CachePeriod) String ¶
func (c CachePeriod) String() string
String returns a human-readable value for this period.
func (*CachePeriod) UnmarshalJSON ¶
func (c *CachePeriod) UnmarshalJSON(data []byte) error
UnmarshalJSON parses the custom JSON format for a cache period. Raw integers are interpreted as seconds.
type CircularPool ¶
type CircularPool interface { Pool // TryGet will never block. It will attempt to grab an object from the pool, // returning nil and false if it cannot do so. TryGet() (interface{}, bool) // GetCancel will wait for an available object with cancellation semantics // similar to golang's Context. Any activity, such as close, on the supplied // channel will interrupt the wait and this method will return nil and false. GetCancel(<-chan struct{}) (interface{}, bool) // GetTimeout will wait for an available object for the specified timeout. // If the timeout is not positive, it behaves exactly as TryGet. Otherwise, this // method waits the given duration for an available object, returning nil // and false if the timeout elapses without an available object. GetTimeout(time.Duration) (interface{}, bool) // GetOrNew will never block. If the pool is exhausted, the new function // will be used to create a new object. This can be used to allow the number // objects to grow beyond the size of the pool. However, when Put is called, // and this pool is full, the object is dropped. GetOrNew() interface{} }
CircularPool represents a fixed-size pool whose objects rotate in and out. Like sync.Pool, clients should not expect any relationship between objects obtained from a CircularPool and objects put into a CircularPool.
Get will block until an object is returned to the pool. GetOrNew, however, will create a new object if the pool is exhausted. This allows a client a choice between being limited by the pool or treating the pool as the minimum amount of objects to keep around.
Put will drop objects if invoked when the pool is full. This can happen if a client uses GetOrNew.
The main difference between CircularPool and sync.Pool is that objects within a CircularPool will not get deallocated. This makes a CircularPool appropriate for times when a statically-sized pool of permanent objects is desired.
A CircularPool is a very flexible concurrent data structure. It can be used as a simple pool of objects for canonicalization. It can also be used for rate limiting or any situation where a lease is required.
func NewCircularPool ¶
func NewCircularPool(initialSize, maxSize int, new func() interface{}) (CircularPool, error)
NewCircularPool creates a fixed-size rotating object pool. maxSize is the maximum number of objects in the pool, while initialSize controls how many objects are preallocated. Setting initialSize to 0 yields an initially empty pool. If maxSize < 1 or initialSize > maxSize, and error is returned.
The new function is used to create objects for the pool. This function cannot be nil, or an error is returned, and must be safe for concurrent execution. If initialSize > 0, then the new function is used to preallocate objects for the pool.
For an initially empty pool, be aware that Get will block forever. In that case, another goroutine must call Put in order to release the goroutine waiting on Get. Initially empty pools are appropriate as concurrent barriers, for example.
type Pool ¶
type Pool interface { // Get fetches an object from the pool. Implementations will vary on // the behavior of an empty pool. Get() interface{} // Put inserts and object into the pool. Get and Put are typically used // with the same type, though that is not necessarily enforced. Put(value interface{}) }
Pool represents an object pool. sync.Pool satisfies this interface, as does CircularPool from this package.
type Value ¶
type Value interface { // Load returns the value object. The mechanism used to obtain the value can // be arbitrarily complex and might fail. For example, an external resource // such as an http server might be consulted. Load() (interface{}, error) }
Value fronts an arbitrary object resulting from some nontrivial operation. For example, the parsed object resulting from a JSON message, or a secure key resulting from parsing a PEM block.
This type is subtley different from atomic.Value. This Value type should be assumed to use an external resource or some complex algorithm in order to obtain its values. That's why Load() returns an error secondary parameter.
func NewValue ¶
func NewValue(source Value, period CachePeriod) (Value, error)
NewValue creates a dynamic implementation of Value based on the period parameter.
If period is 0 (CachePeriodForever), this function will immediately attempt to invoke source.Load() and return a singleton Value. If source.Load() fails, this function returns nil plus that error.