Consider the case when you need to write an HTTP handler that greets a user. However, the localized strings are stored at some remote HTTP server, and those localizations rarely change. To reduce the network traffic and improve response times it is profitable to bulk retrieve the translations from remote and cache them in a local cache.
In this sample we show how to write and test a cache along with creating HTTP requests. If you wish to cache data from database prefer using cache specializations for DB.
To create a non LRU cache cache you have to derive from components::CachingComponentBase, call CacheUpdateTrait::StartPeriodicUpdates() at the component constructor and CacheUpdateTrait::StopPeriodicUpdates() at the destructor:
At the end of the MergeAndSetData function the components::CachingComponentBase::Set() invocation stores data as a new cache.
Update time from remote stored into last_update_remote_. Clocks on different hosts are usually out of sync, so it is better to store the remote time if possible, rather than using a local times from last_update and now input parameters.
components_manager:components:# Configuring components that were registered via component_listcache-http-translations:translations-url:'mockserver/v1/translations'# Some other microservice listens on this URLupdate-types:full-and-incrementalfull-update-interval:1hupdate-interval:15m
A production ready service would dynamically retrieve the above options at runtime from a configuration service. See Writing your own configs server for insights on how to change the above options on the fly, without restarting the service.
Cache component usage
Now the cache could be used just as any other component. For example, a handler could get a reference to the cache and use it in HandleRequestThrow:
Finally, after writing down the dynamic configuration values into file at dynamic-config-fallbacks.fallback-path, we add our component to the components::MinimalServerComponentList(), and start the server with static configuration kStaticConfig.
To build the sample, execute the following build steps at the userver root directory:
mkdir build_release
cd build_release
cmake -DCMAKE_BUILD_TYPE=Release ..
make userver-samples-http_caching
Note that you need a running translations service with bulk handlers to start the service. You could use the mongo service for that purpose.
The sample could be started by running make start-userver-samples-http_caching. The command would invoke testsuite start target that sets proper paths in the configuration files and starts the service.
To start the service manually run ./samples/http_caching/userver-samples-http_caching -c </path/to/static_config.yaml> (do not forget to prepare the configuration files!).
Now you can send a request to your server from another terminal:
$ curl -X POST http://localhost:8089/samples/greet?username=Dear+Developer -i
HTTP/1.1 200 OK
Date: Thu, 09 Dec 2021 17:01:44 UTC
Content-Type: text/html; charset=utf-8
X-YaRequestId: 94193f99ebf94eb58252139f2e9dace4
X-YaSpanId: 4e17e02dfa7b8322
X-YaTraceId: 306d2d54fd0543c09376a5c4bb120a88
Server: userver/1.0.0 (20211209085954; rv:d05d059a3)
Connection: keep-alive
Content-Length: 61
Привет, Dear Developer! Добро пожаловать