Cache components derived from components::CachingComponentBase support cache dumps. If enabled, the cache periodically writes a snapshot of the data to a dump file. When a cache component starts and a suitable dump exists, the cache reads a dump and skips the synchronous Update
.
Advantages:
Update
that may query a database or make some other network requests.Disadvantages:
0. Make a caching component, for example as in Pre-caching data from HTTP remote.
components_manager:
components:
simple-dumped-cache:
update-types: only-full
update-interval: 1m
# that's how we turn it on
dump:
enable: true
world-readable: false
format-version: 0
first-update-mode: required
first-update-type: full
In order for a data type to be serialized for cache dumps the Write
and Read
functions must be implemented in the namespace of the type or in namespace dump
:
std::chrono
, enum
, uuid
in <userver/dump/common.hpp>
std::optional
, utils::StrongTypedef
, std::{unique,shared}_ptr
in <userver/dump/common_containers.hpp>
<userver/dump/aggregates.hpp>
, but you will have to enable dumps manually: Write
/Read
if it suites your requirements.Write
/Read
function declarations for your own types:namespace
of the type, not into namespace dump
namespace dump
Write1, Read1, Write2, Read2, ...
Write/Read
functions by ADL (argument dependent lookup), prefer calling writer.Write(value)
or reader.Read<T>()
.If you have written your own Write/Read
functions, write utest
tests for them using <userver/dump/test_helpers.hpp>
. If the data type supports operator==
, it is sufficient to use dump::TestWriteReadCycle.
By default, the data in the file is stored using an insecure format (binary or JSON). A user with access to the dump file can restore its contents. If the dump file is compromised, a malicious user can gain access to the data. This may be undesirable in the case of caches that store personal or other private data. For such caches, you can enable encryption of the dump file. Dump encryption is disabled by default.
The components::CachingComponentBase uses the AES-GCM-256 encryption algorithm if the encryption is enabled. To enable encryption, do the following:
dump.encrypted=true
: components_manager:
components:
your-caching-component:
dump:
encrypted: true
CACHE_DUMP_SECRET_KEYS
section of the components::Secdist file. Use the name of your cache component as a JSON key and the secret as a JSON value: Static settings for dumps are set in the dump
subsection of the cache component. All the dump
options are described in the dump::Dumper.
An example with all the options:
components_manager:
components:
simple-dumped-cache:
update-types: only-incremental
update-interval: 1m
dump:
enable: true
world-readable: false
format-version: 4
first-update-mode: skip
first-update-type: incremental
max-age: 60m
max-count: 1
min-interval: 3m
fs-task-processor: my-task-processor
wait-for-first-update: true
encrypted: false
A subset of dump settings could be overridden by the dynamic configuration USERVER_DUMPS.
If you omit setting the dynamic configuration (or do not describe some cache in USERVER_DUMPS), the value from the static configuration is used. To reset to the default value, you need to specify null
in the dynamic configuration.
Example:
Update
in a separate fs-task-processor
. Write
and Read
are also called in that task processor.Update
the previous write to the dump has not completed, the new write operation is skipped.format-version
, for example 2020-10-28T174608.907090Z-v0
.tmp
file is created, flushed on the disk and atomically renamed.0755
0400
or 0444
, depending on the world-readable
setting.0
and other small numbers occupy 1 byte. Large and negative numbers take up to 9 bytesstd::string
, std::optional
, containers occupy 1 bytenullptr
that lies there. To prevent this from causing an exception, you will have to redefine void MayReturnNull() override { return true; }
and first-update-fail-ok: true
Write
/Read
for your data type to throw cache::EmptyCacheError
when the cache value is empty. If there is a standard datatype in the cache, you will have to wrap it in a struct
to define a custom Write
/Read
.std::shared_ptr
s for the same object are stored in the same cache snapshot, they will point to separate copies of this object after the dump is loaded.<userver/dump/unsafe.hpp>