Commit graph

4 commits

Author SHA1 Message Date
Derick Alangi
7a37358da5 Settings: Remove unstable markers and mark interfaces appropriately
CachedSource is newable and stable to call while the other interfaces
are now stable to implement.

Change-Id: Ifcb4865691cb7ec308acac2bd3f367b14424a0e1
2022-07-11 13:32:11 +01:00
Dan Duvall
a824da0f34 Support stale cached settings for failover
Require a `CacheableSource` implementation to signal whether stale
settings may be served from the cache by implementing an
`allowsStaleLoad()` method. This will be useful for sources (e.g. etcd)
that expect some degree of unavailability and failover during
unavailability is desired.

In order to support stale results, `CachedSource` sets cache items with
an indefinite TTL but uses the computed expiry timestamp in the envelope
to consider whether the item is considered expired as opposed to a true
miss where the item is malformed or not present in the cache store.  If
a `SettingsBuilderException` is thrown during the source's `load()`
method but the cache check was not a real miss, the stale cached results
are returned.

Note there is currently no pruning of cache items so it is advised that
`CacheableSource` implementations for which stale loads are allowed also
implement an immutable `getHashKey()` based on constructor arguments.

Bug: T296771
Change-Id: Ida0698a237dc0939230799700b6f54956f033d50
2022-01-21 13:31:09 -08:00
Dan Duvall
9fb695d75c Refactor cache TTL for SettingsBuilder sources
Move cache TTL from `CachedSource` into the `CacheableSource` interface,
allowing each source to define a TTL most appropriate to its own
settings loading implementation.

Fix bug where `generation` time was computed incorrectly by `CachedSource`.

Include tests to exercise all `CachedSource` interactions with
`CacheInterface` and `CacheableSource`.

Bug: T296771
Change-Id: I97c42cf6ca716516c32104de25245aa21ec110e4
2021-12-02 09:53:46 -08:00
Dan Duvall
d83a7bcd09 Cache loading of SettingsBuilder sources
The `SettingsBuilder` now accepts a PSR-16 cache interface with which to
store and query settings before attempting to load from each source. By
default, no cache is used, but any object that implements the
`Psr\SimpleCache\CacheInterface` may be provided to the constructor.

An explicit dependency on "psr/simple-cache" has been added to
`composer.json`. Note that this dependency already existed in vendor
albeit it as a transitive one.

An APCu based `SharedMemoryCache` adapter is provided as a canonical
PSR-16 compliant interface for production use.

Sources are now queued by the `SettingsBuilder` when calling `load()`.
If a cache interface has been provided, and the source is considered
cacheable (implements `CacheableSource`), then it is wrapped as a
`CachedSource` which will query the cache first before loading from the
wrapped source.

Cache stampedes are mitigated using probabilistic early expiry. The
implementation for this was partially based on symfony/cache-contract
source code but also from the Wikipedia article and paper referenced
therein.

See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration

Bug: T294748
Change-Id: I52ab3899731546876ee58265bd4a1927886746dc
2021-11-29 12:54:59 -08:00