An ability to change service behavior at runtime without restarting the service is priceless! We have that ability, it is called dynamic configs and it allows you:
to dynamically switch from one HTTP proxy to another or turn off proxying (USERVER_HTTP_PROXY)
to write your own runtime dynamic configs:
to create experiments that could be adjusted or turned on/off without service restarts
to do whatever you like
In previous example we made a simple HTTP server with some dynamic configs set in stone. To make the dynamic configs dynamic for real the following steps should be done:
Handle* functions are invoked concurrently on the same instance of the handler class. Use synchronization primitives or do not modify shared data in Handle*.
Note the rcu::Variable. There may be (and will be!) multiple concurrent requests and the HandleRequestJsonThrow would be invoked concurrently on the same instance of ConfigDistributor. The rcu::Variable allows us to atomically update the config value, concurrently with the HandleRequestJsonThrow invocations.
Function ConfigDistributor::SetNewValues is meant for setting config values to send. For example, you can write another component that accepts JSON requests with new config values and puts those values into ConfigDistributor via SetNewValues(new_values).
HandleRequestJsonThrow
All the interesting things happen in the HandleRequestJsonThrow function, where we grab a rcu::Variable snapshot, fill the update time and the configuration from it:
To build the sample, execute the following build steps at the userver root directory:
bash
mkdir build_release
cd build_release
cmake -DCMAKE_BUILD_TYPE=Release ..
make userver-samples-config_service
The sample could be started by running make start-userver-samples-config_service. 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/config_service/userver-samples-config_service -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:
bash
$ curl -X POST -d '{}' 127.0.0.1:8083/configs/values | jq
Note that there is a ready to use opensource uservice-dynconf dynamic configs service. Use it for your projects or just disable dynamic config updates and keep developing without a supplementary service.