From 29026e1d7bf03b492a2de1c19ece66a252c14a2e Mon Sep 17 00:00:00 2001 From: Tao He Date: Sat, 1 Jul 2023 18:53:31 +0800 Subject: [PATCH] Format source code using clformat Signed-off-by: Tao He --- .clang-format | 15 + .github/workflows/build-test.yml | 42 +- CMakeLists.txt | 11 + etcd/Client.hpp | 1520 +++++++++++++------------- etcd/KeepAlive.hpp | 211 ++-- etcd/Response.hpp | 466 ++++---- etcd/SyncClient.hpp | 1699 ++++++++++++++++-------------- etcd/Value.hpp | 198 ++-- etcd/Watcher.hpp | 424 ++++---- etcd/v3/Action.hpp | 119 +-- etcd/v3/AsyncGRPC.hpp | 762 +++++++------- etcd/v3/KeyValue.hpp | 24 +- etcd/v3/Transaction.hpp | 85 +- etcd/v3/V3Response.hpp | 105 +- etcd/v3/action_constants.hpp | 117 +- src/Client.cpp | 725 +++++++------ src/KeepAlive.cpp | 119 ++- src/Response.cpp | 131 +-- src/SyncClient.cpp | 755 +++++++------ src/Value.cpp | 74 +- src/Watcher.cpp | 386 +++---- src/v3/Action.cpp | 61 +- src/v3/AsyncGRPC.cpp | 940 ++++++++--------- src/v3/KeyValue.cpp | 15 +- src/v3/Transaction.cpp | 283 ++--- src/v3/V3Response.cpp | 89 +- src/v3/action_constants.cpp | 68 +- tst/AuthTest.cpp | 39 +- tst/CampaignTest.cpp | 17 +- tst/ElectionTest.cpp | 29 +- tst/EtcdSyncTest.cpp | 73 +- tst/EtcdTest.cpp | 219 ++-- tst/ForkTest.cpp | 24 +- tst/KeepAliveTest.cpp | 31 +- tst/LockTest.cpp | 96 +- tst/MemLeakTest.cpp | 48 +- tst/MemLeakWatcherTest.cpp | 20 +- tst/RewatchTest.cpp | 55 +- tst/SecurityChannelTest.cpp | 39 +- tst/TransactionTest.cpp | 20 +- tst/WatcherTest.cpp | 96 +- 41 files changed, 5125 insertions(+), 5125 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..a674c1f --- /dev/null +++ b/.clang-format @@ -0,0 +1,15 @@ +BasedOnStyle: Google +DerivePointerAlignment: false +PointerAlignment: Left +Cpp11BracedListStyle: true +IndentCaseLabels: false +AllowShortBlocksOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +Standard: 'Cpp11' +SpaceAfterCStyleCast: true +AlignAfterOpenBracket: Align +SortIncludes: true +IncludeBlocks: Preserve +ForEachMacros: + - BOOST_FOREACH diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 6ace002..2ccdc79 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -82,6 +82,10 @@ jobs: wget https://github.com/Kitware/CMake/releases/download/v3.19.3/cmake-3.19.3-Linux-x86_64.sh sudo bash cmake-3.19.3-Linux-x86_64.sh --prefix /usr --skip-license + # install clang-format + sudo curl -L https://github.com/muttleyxd/clang-tools-static-binaries/releases/download/master-1d7ec53d/clang-format-11_linux-amd64 --output /usr/bin/clang-format + sudo chmod +x /usr/bin/clang-format + - name: Install grpc v1.27.x for Ubuntu 18.04 if: matrix.os == 'ubuntu-18.04' run: | @@ -170,7 +174,7 @@ jobs: if: false uses: mxschmitt/action-tmate@v3 - - name: Build + - name: CMake run: | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu @@ -182,6 +186,42 @@ jobs: -DBUILD_ETCD_TESTS=ON \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + - name: Format + if: runner.os == 'Linux' + run: | + cd build + + function prepend() { while read line; do echo "${1}${line}"; done; } + + make etcd_cpp_apiv3_clformat + GIT_DIFF=$(git diff --ignore-submodules) + if [[ -n $GIT_DIFF ]]; then + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "| clang-format failures found!" + echo "|" + echo "$GIT_DIFF" | prepend "| " + echo "|" + echo "| Run: " + echo "|" + echo "| make etcd_cpp_apiv3_clformat" + echo "|" + echo "| to fix this error." + echo "|" + echo "| Ensure you are working with clang-format-11, which can be obtained from" + echo "|" + echo "| https://github.com/muttleyxd/clang-tools-static-binaries/releases " + echo "|" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + exit -1 + fi + + + - name: Build + run: | + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu + + cd build make -j`nproc` sudo make install diff --git a/CMakeLists.txt b/CMakeLists.txt index 0490731..03266a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -223,6 +223,17 @@ install(EXPORT etcd-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/etcd-cpp-api ) +file(GLOB_RECURSE FILES_NEED_FORMAT + "etcd/*.hpp" + "src/*.cpp" + "tst/*.cpp" +) + +add_custom_target(etcd_cpp_apiv3_clformat + COMMAND clang-format --style=file -i ${FILES_NEED_FORMAT} + COMMENT "Running clang-format, using clang-format-11 from https://github.com/muttleyxd/clang-tools-static-binaries/releases" + VERBATIM) + # deb/rpc packaging for Linux set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}) diff --git a/etcd/Client.hpp b/etcd/Client.hpp index c59cfe2..6fc0da9 100644 --- a/etcd/Client.hpp +++ b/etcd/Client.hpp @@ -14,761 +14,817 @@ #include "etcd/SyncClient.hpp" #include "etcd/v3/action_constants.hpp" -namespace etcd -{ - /** - * Client is responsible for maintaining a connection towards an etcd server. - * Etcd operations can be reached via the methods of the client. - */ - class Client - { - public: - /** - * Constructs an async etcd client object from an established synchronous client. - * - * @param sync_client The synchronous client to use for the async client. - */ - Client(SyncClient *client); - - /** - * Constructs an async etcd client object from an established synchronous client. - * - * @param sync_client The synchronous client to use for the async client. - */ - static Client* WithClient(SyncClient *client); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - Client(std::string const & etcd_url, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param arguments user provided grpc channel arguments. - */ - Client(std::string const & etcd_url, +namespace etcd { +/** + * Client is responsible for maintaining a connection towards an etcd server. + * Etcd operations can be reached via the methods of the client. + */ +class Client { + public: + /** + * Constructs an async etcd client object from an established synchronous + * client. + * + * @param sync_client The synchronous client to use for the async client. + */ + Client(SyncClient* client); + + /** + * Constructs an async etcd client object from an established synchronous + * client. + * + * @param sync_client The synchronous client to use for the async client. + */ + static Client* WithClient(SyncClient* client); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + Client(std::string const& etcd_url, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param arguments user provided grpc channel arguments. + */ + Client(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - static Client *WithUrl(std::string const & etcd_url, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param arguments user provided grpc channel arguments. - */ - static Client *WithUrl(std::string const & etcd_url, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + static Client* WithUrl(std::string const& etcd_url, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param arguments user provided grpc channel arguments. + */ + static Client* WithUrl(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - */ - Client(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl = 300, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param arguments user provided grpc channel arguments. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - * Default value should be 300. - */ - Client(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. + */ + Client(std::string const& etcd_url, std::string const& username, + std::string const& password, int const auth_token_ttl = 300, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. Default value should be 300. + */ + Client(std::string const& etcd_url, std::string const& username, + std::string const& password, int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - */ - static Client *WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl = 300, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param arguments user provided grpc channel arguments. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - * Default value should be 300. - */ - static Client *WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. + */ + static Client* WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, + int const auth_token_ttl = 300, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. Default value should be 300. + */ + static Client* WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - Client(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param arguments user provided grpc channel arguments. - */ - Client(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + Client(std::string const& etcd_url, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param arguments user provided grpc channel arguments. + */ + Client(std::string const& etcd_url, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param target_name_override Override the target host name if you want to pass multiple address - * for load balancing with SSL, and there's no DNS. The @target_name_override@ must exist in the - * SANS of your SSL certificate. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - static Client *WithSSL(std::string const & etcd_url, - std::string const & ca, - std::string const & cert = "", - std::string const & privkey = "", - std::string const & target_name_override = "", - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param target_name_override Override the target host name if you want to pass multiple address - * for load balancing with SSL, and there's no DNS. The @target_name_override@ must exist in the - * SANS of your SSL certificate. - * @param arguments user provided grpc channel arguments. - */ - static Client *WithSSL(std::string const & etcd_url, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param target_name_override Override the target host name if you want to + * pass multiple address for load balancing with SSL, and there's no DNS. The + * @target_name_override@ must exist in the SANS of your SSL certificate. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + static Client* WithSSL(std::string const& etcd_url, std::string const& ca, + std::string const& cert = "", + std::string const& privkey = "", + std::string const& target_name_override = "", + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param target_name_override Override the target host name if you want to + * pass multiple address for load balancing with SSL, and there's no DNS. The + * @target_name_override@ must exist in the SANS of your SSL certificate. + * @param arguments user provided grpc channel arguments. + */ + static Client* WithSSL(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments, + grpc::ChannelArguments const& arguments, #else - grpc_impl::ChannelArguments const & arguments, + grpc_impl::ChannelArguments const& arguments, #endif - std::string const & ca, - std::string const & cert = "", - std::string const & privkey = "", - std::string const & target_name_override = ""); - - ~Client(); - - /** - * Get the HEAD revision of the connected etcd server. - */ - pplx::task head(); - - /** - * Get the value of specified key from the etcd server - * @param key is the key to be read - */ - pplx::task get(std::string const & key); - - /** - * Get the value of specified key of specified revision from the etcd server - * @param key is the key to be read - * @param revision is the revision of the key to be read - */ - pplx::task get(std::string const & key, int64_t revision); - - /** - * Sets the value of a key. The key will be modified if already exists or created - * if it does not exists. - * @param key is the key to be created or modified - * @param value is the new value to be set - */ - pplx::task set(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Sets the value of a key. The key will be modified if already exists or created - * if it does not exists. - * @param key is the key to be created or modified - * @param value is the new value to be set - * @param leaseId is the lease attached to the key - */ - pplx::task set(std::string const & key, std::string const & value, int64_t leaseId); - - - /** - * Creates a new key and sets it's value. Fails if the key already exists. - * @param key is the key to be created - * @param value is the value to be set - */ - pplx::task add(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Creates a new key and sets it's value. Fails if the key already exists. - * @param key is the key to be created - * @param value is the value to be set - * @param leaseId is the lease attached to the key - */ - pplx::task add(std::string const & key, std::string const & value, int64_t leaseId); - - /** - * Put a new key-value pair. - * @param key is the key to be put - * @param value is the value to be put - */ - pplx::task put(std::string const & key, std::string const & value); - - /** - * Modifies an existing key. Fails if the key does not exists. - * @param key is the key to be modified - * @param value is the new value to be set - */ - pplx::task modify(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Modifies an existing key. Fails if the key does not exists. - * @param key is the key to be modified - * @param value is the new value to be set - * @param leaseId is the lease attached to the key - */ - pplx::task modify(std::string const & key, std::string const & value, int64_t leaseId); - - /** - * Modifies an existing key only if it has a specific value. Fails if the key does not exists - * or the original value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_value is the value to be replaced - */ - pplx::task modify_if(std::string const & key, std::string const & value, std::string const & old_value, int ttl = 0); - - /** - * Modifies an existing key only if it has a specific value. Fails if the key does not exists - * or the original value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_value is the value to be replaced - * @param leaseId is the lease attached to the key - */ - pplx::task modify_if(std::string const & key, std::string const & value, std::string const & old_value, int64_t leaseId); - - /** - * Modifies an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of the previous value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_index is the expected index of the original value - */ - pplx::task modify_if(std::string const & key, std::string const & value, int64_t old_index, int ttl = 0); - - /** - * Modifies an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of the previous value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_index is the expected index of the original value - * @param leaseId is the lease attached to the key - */ - pplx::task modify_if(std::string const & key, std::string const & value, int64_t old_index, int64_t leaseId); - - /** - * Removes a single key. The key has to point to a plain, non directory entry. - * @param key is the key to be deleted - */ - pplx::task rm(std::string const & key); - - /** - * Removes a single key but only if it has a specific value. Fails if the key does not exists - * or the its value differs from the expected one. - * @param key is the key to be deleted - */ - pplx::task rm_if(std::string const & key, std::string const & old_value); - - /** - * Removes an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of it differs from the expected one. - * @param key is the key to be deleted - * @param old_index is the expected index of the existing value - */ - pplx::task rm_if(std::string const & key, int64_t old_index); - - /** - * Removes a directory node. Fails if the parent directory dos not exists or not a directory. - * @param key is the directory to be created to be listed - * @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory. - */ - pplx::task rmdir(std::string const & key, bool recursive = false); - - /** - * Removes multiple keys between [key, range_end). - * - * This overload for `const char *` is to avoid const char * to bool implicit casting. - * - * @param key is the directory to be created to be listed - * @param range_end is the end of key range to be removed. - */ - pplx::task rmdir(std::string const & key, const char *range_end); - - /** - * Removes multiple keys between [key, range_end). - * - * @param key is the directory to be created to be listed - * @param range_end is the end of key range to be removed. - */ - pplx::task rmdir(std::string const & key, std::string const &range_end); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * @param key is the key to be listed - */ - pplx::task ls(std::string const & key); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - */ - pplx::task ls(std::string const & key, size_t const limit); - - /** - * Gets a directory listing of the directory prefixed by the key with given revision. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - * @param revision is the revision to be listed - */ - pplx::task ls(std::string const & key, size_t const limit, int64_t revision); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end). - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - */ - pplx::task ls(std::string const & key, std::string const &range_end); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end), and respects the given limit. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - */ - pplx::task ls(std::string const & key, std::string const &range_end, size_t const limit); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end), and respects the given limit and revision. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - * @param revision is the revision to be listed - */ - pplx::task ls(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - */ - pplx::task keys(std::string const & key); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - */ - pplx::task keys(std::string const & key, size_t const limit); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - * @param revision is the revision to be listed - */ - pplx::task keys(std::string const & key, size_t const limit, int64_t revision); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end), and respects the given limit. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - */ - pplx::task keys(std::string const & key, std::string const &range_end); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end). - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - */ - pplx::task keys(std::string const & key, std::string const &range_end, size_t const limit); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end). - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - * @param revision is the revision to be listed - */ - pplx::task keys(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision); - - /** - * Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and - * a new key is created, like "/testdir/newkey" then no change happened in the value of - * "/testdir" so your watch will not detect this. If you want to detect addition and deletion of - * directory entries then you have to do a recursive watch. - * @param key is the value or directory to be watched - * @param recursive if true watch a whole subtree - */ - pplx::task watch(std::string const & key, bool recursive = false); - - /** - * Watches for changes of a key or a subtree from a specific index. The index value can be in the "past". - * @param key is the value or directory to be watched - * @param fromIndex the first index we are interested in - * @param recursive if true watch a whole subtree - */ - pplx::task watch(std::string const & key, int64_t fromIndex, bool recursive = false); - - /** - * Watches for changes of a range of keys inside [key, range_end). - * - * This overload for `const char *` is to avoid const char * to bool implicit casting. - * - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - */ - pplx::task watch(std::string const & key, const char *range_end); - - /** - * Watches for changes of a range of keys inside [key, range_end). - * - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - */ - pplx::task watch(std::string const & key, std::string const &range_end); - - /** - * Watches for changes of a range of keys inside [key, range_end) from a specific index. The index value - * can be in the "past". - * - * Watches for changes of a key or a subtree from a specific index. The index value can be in the "past". - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - * @param fromIndex the first index we are interested in - */ - pplx::task watch(std::string const & key, std::string const &range_end, int64_t fromIndex); - - /** - * Grants a lease. - * @param ttl is the time to live of the lease - */ - pplx::task leasegrant(int ttl); - - /** - * Grants a lease. - * @param ttl is the time to live of the lease - */ - pplx::task> leasekeepalive(int ttl); - - /** - * Revoke a lease. - * @param lease_id is the id the lease - */ - pplx::task leaserevoke(int64_t lease_id); - - /** - * Get time-to-live of a lease. - * @param lease_id is the id the lease - */ - pplx::task leasetimetolive(int64_t lease_id); - - /** - * List all alive leases, equivalent to `etcdctl lease list`. - */ - pplx::task leases(); - - /** - * Gains a lock at a key, using a default created lease, using the default lease (10 seconds), with - * keeping alive has already been taken care of by the library. - * @param key is the key to be used to request the lock. - */ - pplx::task lock(std::string const &key); - - /** - * Lock is special, as waiting for lock may cause the thread resources (in the pplx thread pool) to - * be exhausted. So we need to provide a way to let the user to issue a lock without taking the a - * shared thread. - * - * This works like what we have in the sync client, but we can issue such method from the async client - * directly. - * - * That would be useful when use already issue the lock from a controlled thread. See more discussion - * about the target scenario in https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/139 - * - * @param key is the key to be used to request the lock. - */ - pplx::task lock(std::string const &key, const bool sync); - - /** - * Gains a lock at a key, using a default created lease, using the specified lease TTL (in seconds), with - * keeping alive has already been taken care of by the library. - * @param key is the key to be used to request the lock. - * @param lease_ttl is the TTL used to create a lease for the key. - */ - pplx::task lock(std::string const &key, int lease_ttl); - - /** - * Lock, but the sync version. - */ - pplx::task lock(std::string const &key, int lease_ttl, const bool sync); - - /** - * Gains a lock at a key, using a user-provided lease, the lifetime of the lease won't be taken care - * of by the library. - * @param key is the key to be used to request the lock. - */ - pplx::task lock_with_lease(std::string const &key, int64_t lease_id); - - /** - * Lock, but the sync version. - */ - pplx::task lock_with_lease(std::string const &key, int64_t lease_id, const bool sync); - - /** - * Releases a lock at a key. - * @param key is the lock key to release. - */ - pplx::task unlock(std::string const &lock_key); - - /** - * Execute a etcd transaction. - * @param txn is the transaction object to be executed. - */ - pplx::task txn(etcdv3::Transaction const &txn); - - /** - * Campaign for the election @name@. - * - * @param name is the name of election that will campaign for. - * @param lease_id is a user-managed (usually with a `KeepAlive`) lease id. - * @param value is the value for campaign. - * - * @returns a leader key if succeed, consist of - * - * - name: the name of the election - * - key: a generated election key - * - created rev: the revision of the generated key - * - lease: the lease id of the election leader - */ - pplx::task campaign(std::string const &name, int64_t lease_id, - std::string const &value); - - /** - * Updates the value of election with a new value, with leader key returns by - * @campaign@. - * - * @param name is the name of election - * @param lease_id is the user-provided lease id for the proclamation - * @param key is the generated associated key returned by @campaign@ - * @param revision is the created revision of key-value returned by @campaign@ - * @param value is the new value to set. - */ - pplx::task proclaim(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value); - - /** - * Get the current leader proclamation. - * - * @param name is the names of election. - * - * @returns current election key and value. - */ - pplx::task leader(std::string const &name); - - using Observer = SyncClient::Observer; - - /** - * Observe the leader change. - * - * @param name is the names of election to watch. - * - * @returns an observer that holds that action and will cancel the request when being destructed. - */ - std::unique_ptr observe(std::string const &name); - - /** - * Updates the value of election with a new value, with leader key returns by - * @campaign@. - * - * @param name is the name of election - * @param lease_id is the user-provided lease id for the proclamation - * @param key is the generated associated key returned by @campaign@ - * @param revision is the created revision of key-value returned by @campaign@ - */ - pplx::task resign(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision); - - /** - * Return current auth token. - */ - const std::string ¤t_auth_token() const; - - /** - * Obtain the underlying gRPC channel. - */ + std::string const& ca, std::string const& cert = "", + std::string const& privkey = "", + std::string const& target_name_override = ""); + + ~Client(); + + /** + * Get the HEAD revision of the connected etcd server. + */ + pplx::task head(); + + /** + * Get the value of specified key from the etcd server + * @param key is the key to be read + */ + pplx::task get(std::string const& key); + + /** + * Get the value of specified key of specified revision from the etcd server + * @param key is the key to be read + * @param revision is the revision of the key to be read + */ + pplx::task get(std::string const& key, int64_t revision); + + /** + * Sets the value of a key. The key will be modified if already exists or + * created if it does not exists. + * @param key is the key to be created or modified + * @param value is the new value to be set + */ + pplx::task set(std::string const& key, std::string const& value, + int ttl = 0); + + /** + * Sets the value of a key. The key will be modified if already exists or + * created if it does not exists. + * @param key is the key to be created or modified + * @param value is the new value to be set + * @param leaseId is the lease attached to the key + */ + pplx::task set(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Creates a new key and sets it's value. Fails if the key already exists. + * @param key is the key to be created + * @param value is the value to be set + */ + pplx::task add(std::string const& key, std::string const& value, + int ttl = 0); + + /** + * Creates a new key and sets it's value. Fails if the key already exists. + * @param key is the key to be created + * @param value is the value to be set + * @param leaseId is the lease attached to the key + */ + pplx::task add(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Put a new key-value pair. + * @param key is the key to be put + * @param value is the value to be put + */ + pplx::task put(std::string const& key, std::string const& value); + + /** + * Modifies an existing key. Fails if the key does not exists. + * @param key is the key to be modified + * @param value is the new value to be set + */ + pplx::task modify(std::string const& key, std::string const& value, + int ttl = 0); + + /** + * Modifies an existing key. Fails if the key does not exists. + * @param key is the key to be modified + * @param value is the new value to be set + * @param leaseId is the lease attached to the key + */ + pplx::task modify(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Modifies an existing key only if it has a specific value. Fails if the key + * does not exists or the original value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_value is the value to be replaced + */ + pplx::task modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, int ttl = 0); + + /** + * Modifies an existing key only if it has a specific value. Fails if the key + * does not exists or the original value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_value is the value to be replaced + * @param leaseId is the lease attached to the key + */ + pplx::task modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, int64_t leaseId); + + /** + * Modifies an existing key only if it has a specific modification index + * value. Fails if the key does not exists or the modification index of the + * previous value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_index is the expected index of the original value + */ + pplx::task modify_if(std::string const& key, + std::string const& value, int64_t old_index, + int ttl = 0); + + /** + * Modifies an existing key only if it has a specific modification index + * value. Fails if the key does not exists or the modification index of the + * previous value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_index is the expected index of the original value + * @param leaseId is the lease attached to the key + */ + pplx::task modify_if(std::string const& key, + std::string const& value, int64_t old_index, + int64_t leaseId); + + /** + * Removes a single key. The key has to point to a plain, non directory entry. + * @param key is the key to be deleted + */ + pplx::task rm(std::string const& key); + + /** + * Removes a single key but only if it has a specific value. Fails if the key + * does not exists or the its value differs from the expected one. + * @param key is the key to be deleted + */ + pplx::task rm_if(std::string const& key, + std::string const& old_value); + + /** + * Removes an existing key only if it has a specific modification index value. + * Fails if the key does not exists or the modification index of it differs + * from the expected one. + * @param key is the key to be deleted + * @param old_index is the expected index of the existing value + */ + pplx::task rm_if(std::string const& key, int64_t old_index); + + /** + * Removes a directory node. Fails if the parent directory dos not exists or + * not a directory. + * @param key is the directory to be created to be listed + * @param recursive if true then delete a whole subtree, otherwise deletes + * only an empty directory. + */ + pplx::task rmdir(std::string const& key, bool recursive = false); + + /** + * Removes multiple keys between [key, range_end). + * + * This overload for `const char *` is to avoid const char * to bool implicit + * casting. + * + * @param key is the directory to be created to be listed + * @param range_end is the end of key range to be removed. + */ + pplx::task rmdir(std::string const& key, const char* range_end); + + /** + * Removes multiple keys between [key, range_end). + * + * @param key is the directory to be created to be listed + * @param range_end is the end of key range to be removed. + */ + pplx::task rmdir(std::string const& key, + std::string const& range_end); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * @param key is the key to be listed + */ + pplx::task ls(std::string const& key); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + */ + pplx::task ls(std::string const& key, size_t const limit); + + /** + * Gets a directory listing of the directory prefixed by the key with given + * revision. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + * @param revision is the revision to be listed + */ + pplx::task ls(std::string const& key, size_t const limit, + int64_t revision); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end). + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + */ + pplx::task ls(std::string const& key, std::string const& range_end); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end), and respects + * the given limit. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + */ + pplx::task ls(std::string const& key, std::string const& range_end, + size_t const limit); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end), and respects + * the given limit and revision. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + * @param revision is the revision to be listed + */ + pplx::task ls(std::string const& key, std::string const& range_end, + size_t const limit, int64_t revision); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + */ + pplx::task keys(std::string const& key); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + */ + pplx::task keys(std::string const& key, size_t const limit); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + * @param revision is the revision to be listed + */ + pplx::task keys(std::string const& key, size_t const limit, + int64_t revision); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end), and respects the given limit. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + */ + pplx::task keys(std::string const& key, + std::string const& range_end); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end). + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + */ + pplx::task keys(std::string const& key, + std::string const& range_end, size_t const limit); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end). + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + * @param revision is the revision to be listed + */ + pplx::task keys(std::string const& key, + std::string const& range_end, size_t const limit, + int64_t revision); + + /** + * Watches for changes of a key or a subtree. Please note that if you watch + * e.g. "/testdir" and a new key is created, like "/testdir/newkey" then no + * change happened in the value of + * "/testdir" so your watch will not detect this. If you want to detect + * addition and deletion of directory entries then you have to do a recursive + * watch. + * @param key is the value or directory to be watched + * @param recursive if true watch a whole subtree + */ + pplx::task watch(std::string const& key, bool recursive = false); + + /** + * Watches for changes of a key or a subtree from a specific index. The index + * value can be in the "past". + * @param key is the value or directory to be watched + * @param fromIndex the first index we are interested in + * @param recursive if true watch a whole subtree + */ + pplx::task watch(std::string const& key, int64_t fromIndex, + bool recursive = false); + + /** + * Watches for changes of a range of keys inside [key, range_end). + * + * This overload for `const char *` is to avoid const char * to bool implicit + * casting. + * + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + */ + pplx::task watch(std::string const& key, const char* range_end); + + /** + * Watches for changes of a range of keys inside [key, range_end). + * + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + */ + pplx::task watch(std::string const& key, + std::string const& range_end); + + /** + * Watches for changes of a range of keys inside [key, range_end) from a + * specific index. The index value can be in the "past". + * + * Watches for changes of a key or a subtree from a specific index. The index + * value can be in the "past". + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + * @param fromIndex the first index we are interested in + */ + pplx::task watch(std::string const& key, + std::string const& range_end, int64_t fromIndex); + + /** + * Grants a lease. + * @param ttl is the time to live of the lease + */ + pplx::task leasegrant(int ttl); + + /** + * Grants a lease. + * @param ttl is the time to live of the lease + */ + pplx::task> leasekeepalive(int ttl); + + /** + * Revoke a lease. + * @param lease_id is the id the lease + */ + pplx::task leaserevoke(int64_t lease_id); + + /** + * Get time-to-live of a lease. + * @param lease_id is the id the lease + */ + pplx::task leasetimetolive(int64_t lease_id); + + /** + * List all alive leases, equivalent to `etcdctl lease list`. + */ + pplx::task leases(); + + /** + * Gains a lock at a key, using a default created lease, using the default + * lease (10 seconds), with keeping alive has already been taken care of by + * the library. + * @param key is the key to be used to request the lock. + */ + pplx::task lock(std::string const& key); + + /** + * Lock is special, as waiting for lock may cause the thread resources (in the + * pplx thread pool) to be exhausted. So we need to provide a way to let the + * user to issue a lock without taking the a shared thread. + * + * This works like what we have in the sync client, but we can issue such + * method from the async client directly. + * + * That would be useful when use already issue the lock from a controlled + * thread. See more discussion about the target scenario in + * https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/139 + * + * @param key is the key to be used to request the lock. + */ + pplx::task lock(std::string const& key, const bool sync); + + /** + * Gains a lock at a key, using a default created lease, using the specified + * lease TTL (in seconds), with keeping alive has already been taken care of + * by the library. + * @param key is the key to be used to request the lock. + * @param lease_ttl is the TTL used to create a lease for the key. + */ + pplx::task lock(std::string const& key, int lease_ttl); + + /** + * Lock, but the sync version. + */ + pplx::task lock(std::string const& key, int lease_ttl, + const bool sync); + + /** + * Gains a lock at a key, using a user-provided lease, the lifetime of the + * lease won't be taken care of by the library. + * @param key is the key to be used to request the lock. + */ + pplx::task lock_with_lease(std::string const& key, + int64_t lease_id); + + /** + * Lock, but the sync version. + */ + pplx::task lock_with_lease(std::string const& key, int64_t lease_id, + const bool sync); + + /** + * Releases a lock at a key. + * @param key is the lock key to release. + */ + pplx::task unlock(std::string const& lock_key); + + /** + * Execute a etcd transaction. + * @param txn is the transaction object to be executed. + */ + pplx::task txn(etcdv3::Transaction const& txn); + + /** + * Campaign for the election @name@. + * + * @param name is the name of election that will campaign for. + * @param lease_id is a user-managed (usually with a `KeepAlive`) lease id. + * @param value is the value for campaign. + * + * @returns a leader key if succeed, consist of + * + * - name: the name of the election + * - key: a generated election key + * - created rev: the revision of the generated key + * - lease: the lease id of the election leader + */ + pplx::task campaign(std::string const& name, int64_t lease_id, + std::string const& value); + + /** + * Updates the value of election with a new value, with leader key returns by + * @campaign@. + * + * @param name is the name of election + * @param lease_id is the user-provided lease id for the proclamation + * @param key is the generated associated key returned by @campaign@ + * @param revision is the created revision of key-value returned by @campaign@ + * @param value is the new value to set. + */ + pplx::task proclaim(std::string const& name, int64_t lease_id, + std::string const& key, int64_t revision, + std::string const& value); + + /** + * Get the current leader proclamation. + * + * @param name is the names of election. + * + * @returns current election key and value. + */ + pplx::task leader(std::string const& name); + + using Observer = SyncClient::Observer; + + /** + * Observe the leader change. + * + * @param name is the names of election to watch. + * + * @returns an observer that holds that action and will cancel the request + * when being destructed. + */ + std::unique_ptr observe(std::string const& name); + + /** + * Updates the value of election with a new value, with leader key returns by + * @campaign@. + * + * @param name is the name of election + * @param lease_id is the user-provided lease id for the proclamation + * @param key is the generated associated key returned by @campaign@ + * @param revision is the created revision of key-value returned by @campaign@ + */ + pplx::task resign(std::string const& name, int64_t lease_id, + std::string const& key, int64_t revision); + + /** + * Return current auth token. + */ + const std::string& current_auth_token() const; + + /** + * Obtain the underlying gRPC channel. + */ #if defined(WITH_GRPC_CHANNEL_CLASS) - std::shared_ptr grpc_channel() const; + std::shared_ptr grpc_channel() const; #else - std::shared_ptr grpc_channel() const; + std::shared_ptr grpc_channel() const; #endif - /** - * Set a timeout value for grpc operations. - */ - template - void set_grpc_timeout(std::chrono::duration const &timeout) { - this->client->set_grpc_timeout(timeout); - } - - /** - * Get the current timeout value for grpc operations. - */ - std::chrono::microseconds get_grpc_timeout() const { - return this->client->get_grpc_timeout(); - } - - /** - * Obtain the underlying synchronous client. - */ - SyncClient* sync_client() const; - - private: - bool own_client = true; - SyncClient *client = nullptr; + /** + * Set a timeout value for grpc operations. + */ + template + void set_grpc_timeout(std::chrono::duration const& timeout) { + this->client->set_grpc_timeout(timeout); + } + + /** + * Get the current timeout value for grpc operations. + */ + std::chrono::microseconds get_grpc_timeout() const { + return this->client->get_grpc_timeout(); + } + + /** + * Obtain the underlying synchronous client. + */ + SyncClient* sync_client() const; + + private: + bool own_client = true; + SyncClient* client = nullptr; }; -} +} // namespace etcd #endif diff --git a/etcd/KeepAlive.hpp b/etcd/KeepAlive.hpp index 4302b08..97ce9f9 100644 --- a/etcd/KeepAlive.hpp +++ b/etcd/KeepAlive.hpp @@ -10,119 +10,114 @@ #include #include -#include "etcd/SyncClient.hpp" #include "etcd/Response.hpp" +#include "etcd/SyncClient.hpp" + +namespace etcd { +// forward declaration to avoid header/library dependency +class Client; + +/** + * If ID is set to 0, the library will choose an ID, and can be accessed from + * ".Lease()". + */ +class KeepAlive { + public: + KeepAlive(Client const& client, int ttl, int64_t lease_id = 0); + KeepAlive(SyncClient const& client, int ttl, int64_t lease_id = 0); + KeepAlive(std::string const& address, int ttl, int64_t lease_id = 0); + KeepAlive(std::string const& address, std::string const& username, + std::string const& password, int ttl, int64_t lease_id = 0, + int const auth_token_ttl = 300); + + KeepAlive(Client const& client, + std::function const& handler, int ttl, + int64_t lease_id = 0); + KeepAlive(SyncClient const& client, + std::function const& handler, int ttl, + int64_t lease_id = 0); + KeepAlive(std::string const& address, + std::function const& handler, int ttl, + int64_t lease_id = 0); + KeepAlive(std::string const& address, std::string const& username, + std::string const& password, + std::function const& handler, int ttl, + int64_t lease_id = 0, int const auth_token_ttl = 300); + KeepAlive(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::function const& handler, int ttl, + int64_t lease_id = 0, std::string const& target_name_override = ""); + + KeepAlive(KeepAlive const&) = delete; + KeepAlive(KeepAlive&&) = delete; + + int64_t Lease() const { return lease_id; } + + /** + * Stop the keep alive action. + */ + void Cancel(); + + /** + * Check if the keep alive is still valid (invalid when there's an async + * exception). + * + * Nothing will happen if valid and an exception will be rethrowed if invalid. + */ + void Check(); -namespace etcd -{ - // forward declaration to avoid header/library dependency - class Client; + /** + * Set a timeout value for grpc operations. + */ + template + void set_grpc_timeout(std::chrono::duration const& timeout) { + this->grpc_timeout = + std::chrono::duration_cast(timeout); + } /** - * If ID is set to 0, the library will choose an ID, and can be accessed from ".Lease()". + * Get the current timeout value for grpc operations. */ - class KeepAlive - { - public: - KeepAlive(Client const &client, - int ttl, int64_t lease_id = 0); - KeepAlive(SyncClient const &client, - int ttl, int64_t lease_id = 0); - KeepAlive(std::string const & address, - int ttl, int64_t lease_id = 0); - KeepAlive(std::string const & address, - std::string const & username, std::string const & password, - int ttl, int64_t lease_id = 0, - int const auth_token_ttl = 300); - - KeepAlive(Client const &client, - std::function const &handler, - int ttl, int64_t lease_id = 0); - KeepAlive(SyncClient const &client, - std::function const &handler, - int ttl, int64_t lease_id = 0); - KeepAlive(std::string const & address, - std::function const &handler, - int ttl, int64_t lease_id = 0); - KeepAlive(std::string const & address, - std::string const & username, std::string const & password, - std::function const &handler, - int ttl, int64_t lease_id = 0, - int const auth_token_ttl = 300); - KeepAlive(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::function const &handler, - int ttl, int64_t lease_id = 0, - std::string const & target_name_override = ""); - - KeepAlive(KeepAlive const &) = delete; - KeepAlive(KeepAlive &&) = delete; - - int64_t Lease() const { return lease_id; } - - /** - * Stop the keep alive action. - */ - void Cancel(); - - /** - * Check if the keep alive is still valid (invalid when there's an async exception). - * - * Nothing will happen if valid and an exception will be rethrowed if invalid. - */ - void Check(); - - /** - * Set a timeout value for grpc operations. - */ - template - void set_grpc_timeout(std::chrono::duration const &timeout) { - this->grpc_timeout = std::chrono::duration_cast(timeout); - } - - /** - * Get the current timeout value for grpc operations. - */ - std::chrono::microseconds get_grpc_timeout() const { - return this->grpc_timeout; - } - - ~KeepAlive(); - - protected: - // automatically refresh loop - void refresh(); - // refresh once immediately - void refresh_once(); - - struct EtcdServerStubs; - struct EtcdServerStubsDeleter { - void operator()(EtcdServerStubs *stubs); - }; - std::unique_ptr stubs; - - private: - // error handling - std::exception_ptr eptr_; - std::function handler_; - - // Don't use `pplx::task` to avoid sharing thread pool with other actions on the client - // to avoid any potential blocking, which may block the keepalive loop and evict the lease. - std::thread refresh_task_; - - int ttl; - int64_t lease_id; - - // protect the initializing status of `timer`. - std::mutex mutex_for_refresh_; - std::condition_variable cv_for_refresh_; - std::atomic_bool continue_next; - - // grpc timeout in `refresh()` - mutable std::chrono::microseconds grpc_timeout = std::chrono::microseconds::zero(); + std::chrono::microseconds get_grpc_timeout() const { + return this->grpc_timeout; + } + + ~KeepAlive(); + + protected: + // automatically refresh loop + void refresh(); + // refresh once immediately + void refresh_once(); + + struct EtcdServerStubs; + struct EtcdServerStubsDeleter { + void operator()(EtcdServerStubs* stubs); }; -} + std::unique_ptr stubs; + + private: + // error handling + std::exception_ptr eptr_; + std::function handler_; + + // Don't use `pplx::task` to avoid sharing thread pool with other actions on + // the client to avoid any potential blocking, which may block the keepalive + // loop and evict the lease. + std::thread refresh_task_; + + int ttl; + int64_t lease_id; + + // protect the initializing status of `timer`. + std::mutex mutex_for_refresh_; + std::condition_variable cv_for_refresh_; + std::atomic_bool continue_next; + + // grpc timeout in `refresh()` + mutable std::chrono::microseconds grpc_timeout = + std::chrono::microseconds::zero(); +}; +} // namespace etcd #endif diff --git a/etcd/Response.hpp b/etcd/Response.hpp index d37a6d9..c8d72fe 100644 --- a/etcd/Response.hpp +++ b/etcd/Response.hpp @@ -2,8 +2,8 @@ #define __ETCD_RESPONSE_HPP__ #include -#include #include +#include #include #include #include @@ -11,239 +11,243 @@ #include "etcd/Value.hpp" namespace etcdv3 { - class AsyncWatchAction; - class AsyncLeaseKeepAliveAction; - class AsyncObserveAction; - class V3Response; +class AsyncWatchAction; +class AsyncLeaseKeepAliveAction; +class AsyncObserveAction; +class V3Response; +} // namespace etcdv3 + +namespace etcd { +typedef std::vector Keys; + +namespace detail { +// Compute the duration between given start time point and now +inline const std::chrono::microseconds duration_till_now( + std::chrono::high_resolution_clock::time_point const& start_timepoint) { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - start_timepoint); } +} // namespace detail + +// forward declaration +class KeepAlive; +class Watcher; + +/** + * The Reponse object received for the requests of etcd::Client + */ +class Response { + public: + template + static etcd::Response create(std::unique_ptr call) { + call->waitForResponse(); + auto v3resp = call->ParseResponse(); + return etcd::Response(v3resp, + detail::duration_till_now(call->startTimepoint())); + } -namespace etcd -{ - typedef std::vector Keys; - - namespace detail { - // Compute the duration between given start time point and now - inline const std::chrono::microseconds duration_till_now( - std::chrono::high_resolution_clock::time_point const & start_timepoint) { - return std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - start_timepoint); - } + template + static etcd::Response create(std::shared_ptr call) { + call->waitForResponse(); + auto v3resp = call->ParseResponse(); + return etcd::Response(v3resp, + detail::duration_till_now(call->startTimepoint())); } - // forward declaration - class KeepAlive; - class Watcher; - - /** - * The Reponse object received for the requests of etcd::Client - */ - class Response - { - public: - - template - static etcd::Response create(std::unique_ptr call) - { - call->waitForResponse(); - auto v3resp = call->ParseResponse(); - return etcd::Response(v3resp, detail::duration_till_now(call->startTimepoint())); - } - - template - static etcd::Response create(std::shared_ptr call) - { - call->waitForResponse(); - auto v3resp = call->ParseResponse(); - return etcd::Response(v3resp, detail::duration_till_now(call->startTimepoint())); - } - - template - static etcd::Response create(std::unique_ptr call, - std::function callback) - { - call->waitForResponse(callback); - auto v3resp = call->ParseResponse(); - return etcd::Response(v3resp, detail::duration_till_now(call->startTimepoint())); - } - - template - static etcd::Response create(std::function()> fn) - { - auto call = fn(); - - call->waitForResponse(); - auto v3resp = call->ParseResponse(); - return etcd::Response(v3resp, detail::duration_till_now(call->startTimepoint())); - } - - template - static etcd::Response create(std::function()> fn) - { - auto call = fn(); - - call->waitForResponse(); - auto v3resp = call->ParseResponse(); - return etcd::Response(v3resp, detail::duration_till_now(call->startTimepoint())); - } - - Response(); - - Response(const Response &); - - /** - * Returns the error code received from the etcd server. In case of success the error code is 0. - */ - int error_code() const; - - /** - * Returns the string representation of the error code - */ - std::string const & error_message() const; - - /** - * Returns true if this is a successful response - */ - bool is_ok() const; - - /** - * Returns true if the error is a network unavailable error. - */ - bool is_network_unavailable() const; - - /** - * Check whether the response contains a grpc TIMEOUT error. - */ - bool is_grpc_timeout() const; - - /** - * Returns the action type of the operation that this response belongs to. - */ - std::string const & action() const; - - /** - * Returns the current index value of etcd - */ - int64_t index() const; - - /** - * Returns the value object of the response to a get/set/modify operation. - */ - Value const & value() const; - - /** - * Returns the previous value object of the response to a set/modify/rm operation. - */ - Value const & prev_value() const; - - /** - * Returns the index-th value of the response to an 'ls' operation. Equivalent to values()[index] - */ - Value const & value(int index) const; - - /** - * Returns the vector of values in a directory in response to an 'ls' operation. - */ - Values const & values() const; - - /** - * Returns the vector of keys in a directory in response to an 'ls' operation. - */ - Keys const & keys() const; - - /** - * Returns the index-th key in a directory listing. Same as keys()[index] - */ - std::string const & key(int index) const; - - /** - * Returns the compact_revision if the response is a watch-cancelled revision. - * `-1` means uninitialized (the response is not watch-cancelled) - */ - int64_t compact_revision() const; - - /** - * Returns the watcher id for client.watch() requests. `-1` means uninitialized (the response is not for watch). - */ - int64_t watch_id() const; - - /** - * Returns the lock key. - */ - std::string const & lock_key() const; - - /** - * Return the "name" in response. - */ - std::string const & name() const; - - /** - * Returns the watched events. - */ - std::vector const & events() const; - - /** - * Returns the duration of request execution in microseconds. - */ - std::chrono::microseconds const & duration() const; - - /** - * Returns the current cluster id. - */ - uint64_t cluster_id() const; - - /** - * Returns the current member id. - */ - uint64_t member_id() const; - - /** - * Returns ther current raft term. - */ - uint64_t raft_term() const; - - /** - * Returns ther current raft term. - */ - std::vector const & leases() const; - - protected: - Response(const etcdv3::V3Response& response, std::chrono::microseconds const& duration); - Response(int error_code, std::string const& error_message); - Response(int error_code, char const * error_message); - - int _error_code; - std::string _error_message; - int64_t _index; - std::string _action; - Value _value; - Value _prev_value; - Values _values; - Keys _keys; - int64_t _compact_revision = -1; // for watch - int64_t _watch_id = -1; // for watch - std::string _lock_key; // for lock - std::string _name; // for campaign (in v3election) - std::vector _events; // for watch - // execute duration (in microseconds), during the action created and response parsed - std::chrono::microseconds _duration; - - // cluster metadata - uint64_t _cluster_id; - uint64_t _member_id; - uint64_t _raft_term; - - // for lease list - std::vector _leases; - - friend class Client; - friend class SyncClient; - friend class KeepAlive; - friend class Watcher; - - friend class etcdv3::AsyncWatchAction; - friend class etcdv3::AsyncLeaseKeepAliveAction; - friend class etcdv3::AsyncObserveAction; - }; -} + template + static etcd::Response create(std::unique_ptr call, + std::function callback) { + call->waitForResponse(callback); + auto v3resp = call->ParseResponse(); + return etcd::Response(v3resp, + detail::duration_till_now(call->startTimepoint())); + } + + template + static etcd::Response create(std::function()> fn) { + auto call = fn(); + + call->waitForResponse(); + auto v3resp = call->ParseResponse(); + return etcd::Response(v3resp, + detail::duration_till_now(call->startTimepoint())); + } + + template + static etcd::Response create(std::function()> fn) { + auto call = fn(); + + call->waitForResponse(); + auto v3resp = call->ParseResponse(); + return etcd::Response(v3resp, + detail::duration_till_now(call->startTimepoint())); + } + + Response(); + + Response(const Response&); + + /** + * Returns the error code received from the etcd server. In case of success + * the error code is 0. + */ + int error_code() const; + + /** + * Returns the string representation of the error code + */ + std::string const& error_message() const; + + /** + * Returns true if this is a successful response + */ + bool is_ok() const; + + /** + * Returns true if the error is a network unavailable error. + */ + bool is_network_unavailable() const; + + /** + * Check whether the response contains a grpc TIMEOUT error. + */ + bool is_grpc_timeout() const; + + /** + * Returns the action type of the operation that this response belongs to. + */ + std::string const& action() const; + + /** + * Returns the current index value of etcd + */ + int64_t index() const; + + /** + * Returns the value object of the response to a get/set/modify operation. + */ + Value const& value() const; + + /** + * Returns the previous value object of the response to a set/modify/rm + * operation. + */ + Value const& prev_value() const; + + /** + * Returns the index-th value of the response to an 'ls' operation. Equivalent + * to values()[index] + */ + Value const& value(int index) const; + + /** + * Returns the vector of values in a directory in response to an 'ls' + * operation. + */ + Values const& values() const; + + /** + * Returns the vector of keys in a directory in response to an 'ls' operation. + */ + Keys const& keys() const; + + /** + * Returns the index-th key in a directory listing. Same as keys()[index] + */ + std::string const& key(int index) const; + + /** + * Returns the compact_revision if the response is a watch-cancelled revision. + * `-1` means uninitialized (the response is not watch-cancelled) + */ + int64_t compact_revision() const; + + /** + * Returns the watcher id for client.watch() requests. `-1` means + * uninitialized (the response is not for watch). + */ + int64_t watch_id() const; + + /** + * Returns the lock key. + */ + std::string const& lock_key() const; + + /** + * Return the "name" in response. + */ + std::string const& name() const; + + /** + * Returns the watched events. + */ + std::vector const& events() const; + + /** + * Returns the duration of request execution in microseconds. + */ + std::chrono::microseconds const& duration() const; + + /** + * Returns the current cluster id. + */ + uint64_t cluster_id() const; + + /** + * Returns the current member id. + */ + uint64_t member_id() const; + + /** + * Returns ther current raft term. + */ + uint64_t raft_term() const; + + /** + * Returns ther current raft term. + */ + std::vector const& leases() const; + + protected: + Response(const etcdv3::V3Response& response, + std::chrono::microseconds const& duration); + Response(int error_code, std::string const& error_message); + Response(int error_code, char const* error_message); + + int _error_code; + std::string _error_message; + int64_t _index; + std::string _action; + Value _value; + Value _prev_value; + Values _values; + Keys _keys; + int64_t _compact_revision = -1; // for watch + int64_t _watch_id = -1; // for watch + std::string _lock_key; // for lock + std::string _name; // for campaign (in v3election) + std::vector _events; // for watch + // execute duration (in microseconds), during the action created and response + // parsed + std::chrono::microseconds _duration; + + // cluster metadata + uint64_t _cluster_id; + uint64_t _member_id; + uint64_t _raft_term; + + // for lease list + std::vector _leases; + + friend class Client; + friend class SyncClient; + friend class KeepAlive; + friend class Watcher; + + friend class etcdv3::AsyncWatchAction; + friend class etcdv3::AsyncLeaseKeepAliveAction; + friend class etcdv3::AsyncObserveAction; +}; +} // namespace etcd #endif diff --git a/etcd/SyncClient.hpp b/etcd/SyncClient.hpp index 5313f13..6c96b62 100644 --- a/etcd/SyncClient.hpp +++ b/etcd/SyncClient.hpp @@ -12,854 +12,931 @@ #include "etcd/v3/action_constants.hpp" namespace etcdv3 { - struct ActionParameters; - - class AsyncCompareAndDeleteAction; - class AsyncCompareAndSwapAction; - class AsyncDeleteAction; - class AsyncCampaignAction; - class AsyncProclaimAction; - class AsyncLeaderAction; - class AsyncObserveAction; - class AsyncResignAction; - class AsyncHeadAction; - class AsyncLeaseGrantAction; - class AsyncLeaseRevokeAction; - class AsyncLeaseKeepAliveAction; - class AsyncLeaseTimeToLiveAction; - class AsyncLeaseLeasesAction; - class AsyncLockAction; - class AsyncUnlockAction; - class AsyncPutAction; - class AsyncRangeAction; - class AsyncSetAction; - class AsyncTxnAction; - class AsyncUpdateAction; - class AsyncWatchAction; - - enum class AtomicityType; - class Transaction; - - namespace detail { - std::string string_plus_one(std::string const &value); - std::string resolve_etcd_endpoints(std::string const &default_endpoints); - } -} +struct ActionParameters; + +class AsyncCompareAndDeleteAction; +class AsyncCompareAndSwapAction; +class AsyncDeleteAction; +class AsyncCampaignAction; +class AsyncProclaimAction; +class AsyncLeaderAction; +class AsyncObserveAction; +class AsyncResignAction; +class AsyncHeadAction; +class AsyncLeaseGrantAction; +class AsyncLeaseRevokeAction; +class AsyncLeaseKeepAliveAction; +class AsyncLeaseTimeToLiveAction; +class AsyncLeaseLeasesAction; +class AsyncLockAction; +class AsyncUnlockAction; +class AsyncPutAction; +class AsyncRangeAction; +class AsyncSetAction; +class AsyncTxnAction; +class AsyncUpdateAction; +class AsyncWatchAction; + +enum class AtomicityType; +class Transaction; + +namespace detail { +std::string string_plus_one(std::string const& value); +std::string resolve_etcd_endpoints(std::string const& default_endpoints); +} // namespace detail +} // namespace etcdv3 #if defined(WITH_GRPC_CHANNEL_CLASS) namespace grpc { - class Channel; - class ChannelArguments; -} +class Channel; +class ChannelArguments; +} // namespace grpc #else namespace grpc_impl { - class Channel; - class ChannelArguments; -} +class Channel; +class ChannelArguments; +} // namespace grpc_impl #endif -namespace etcd -{ - using etcdv3::ERROR_KEY_NOT_FOUND; - using etcdv3::ERROR_COMPARE_FAILED; - using etcdv3::ERROR_KEY_ALREADY_EXISTS; - using etcdv3::ERROR_ACTION_CANCELLED; - - class KeepAlive; - class Watcher; - class Client; - - /** - * Client is responsible for maintaining a connection towards an etcd server. - * Etcd operations can be reached via the methods of the client. - */ - /** - * SyncClient is a wrapper around etcd::Client and provides a simplified sync interface with blocking operations. - * - * In case of any exceptions occur in the backend the Response value's error_message will contain the - * text of the exception and the error code will be 600 - * - * Use this class only if performance does not matter. - */ - class SyncClient - { - private: - class TokenAuthenticator; - class TokenAuthenticatorDeleter { - public: - void operator()(TokenAuthenticator *authenticator); - }; - - public: - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - SyncClient(std::string const & etcd_url, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param arguments user provided grpc channel arguments. - */ - SyncClient(std::string const & etcd_url, +namespace etcd { +using etcdv3::ERROR_ACTION_CANCELLED; +using etcdv3::ERROR_COMPARE_FAILED; +using etcdv3::ERROR_KEY_ALREADY_EXISTS; +using etcdv3::ERROR_KEY_NOT_FOUND; + +class KeepAlive; +class Watcher; +class Client; + +/** + * Client is responsible for maintaining a connection towards an etcd server. + * Etcd operations can be reached via the methods of the client. + */ +/** + * SyncClient is a wrapper around etcd::Client and provides a simplified sync + * interface with blocking operations. + * + * In case of any exceptions occur in the backend the Response value's + * error_message will contain the text of the exception and the error code will + * be 600 + * + * Use this class only if performance does not matter. + */ +class SyncClient { + private: + class TokenAuthenticator; + class TokenAuthenticatorDeleter { + public: + void operator()(TokenAuthenticator* authenticator); + }; + + public: + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + SyncClient(std::string const& etcd_url, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param arguments user provided grpc channel arguments. + */ + SyncClient(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - static SyncClient *WithUrl(std::string const & etcd_url, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param arguments user provided grpc channel arguments. - */ - static SyncClient *WithUrl(std::string const & etcd_url, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + static SyncClient* WithUrl(std::string const& etcd_url, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param arguments user provided grpc channel arguments. + */ + static SyncClient* WithUrl(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - */ - SyncClient(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl = 300, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param arguments user provided grpc channel arguments. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - * Default value should be 300. - */ - SyncClient(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. + */ + SyncClient(std::string const& etcd_url, std::string const& username, + std::string const& password, int const auth_token_ttl = 300, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. Default value should be 300. + */ + SyncClient(std::string const& etcd_url, std::string const& username, + std::string const& password, int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - */ - static SyncClient *WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl = 300, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param username username of etcd auth - * @param password password of etcd auth - * @param arguments user provided grpc channel arguments. - * @param auth_token_ttl TTL seconds for auth token, see also `--auth-token-ttl` flags of etcd. - * Default value should be 300. - */ - static SyncClient *WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. + */ + static SyncClient* WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, + int const auth_token_ttl = 300, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param username username of etcd auth + * @param password password of etcd auth + * @param arguments user provided grpc channel arguments. + * @param auth_token_ttl TTL seconds for auth token, see also + * `--auth-token-ttl` flags of etcd. Default value should be 300. + */ + static SyncClient* WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, + int const auth_token_ttl, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - SyncClient(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param arguments user provided grpc channel arguments. - */ - SyncClient(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + SyncClient(std::string const& etcd_url, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param arguments user provided grpc channel arguments. + */ + SyncClient(std::string const& etcd_url, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments + grpc::ChannelArguments const& arguments #else - grpc_impl::ChannelArguments const & arguments + grpc_impl::ChannelArguments const& arguments #endif - ); - - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param target_name_override Override the target host name if you want to pass multiple address - * for load balancing with SSL, and there's no DNS. The @target_name_override@ must exist in the - * SANS of your SSL certificate. - * @param load_balancer is the load balance strategy, can be one of round_robin/pick_first/grpclb/xds. - */ - static SyncClient *WithSSL(std::string const & etcd_url, - std::string const & ca, - std::string const & cert = "", - std::string const & privkey = "", - std::string const & target_name_override = "", - std::string const & load_balancer = "round_robin"); - - /** - * Constructs an etcd client object. - * - * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:2379", - * or multiple url, separated by ',' or ';'. - * @param ca root CA file for SSL/TLS connection. - * @param cert cert chain file for SSL/TLS authentication, could be empty string. - * @param privkey private key file for SSL/TLS authentication, could be empty string. - * @param target_name_override Override the target host name if you want to pass multiple address - * for load balancing with SSL, and there's no DNS. The @target_name_override@ must exist in the - * SANS of your SSL certificate. - * @param arguments user provided grpc channel arguments. - */ - static SyncClient *WithSSL(std::string const & etcd_url, + ); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param target_name_override Override the target host name if you want to + * pass multiple address for load balancing with SSL, and there's no DNS. The + * @target_name_override@ must exist in the SANS of your SSL certificate. + * @param load_balancer is the load balance strategy, can be one of + * round_robin/pick_first/grpclb/xds. + */ + static SyncClient* WithSSL(std::string const& etcd_url, std::string const& ca, + std::string const& cert = "", + std::string const& privkey = "", + std::string const& target_name_override = "", + std::string const& load_balancer = "round_robin"); + + /** + * Constructs an etcd client object. + * + * @param etcd_url is the url of the etcd server to connect to, like + * "http://127.0.0.1:2379", or multiple url, separated by ',' or ';'. + * @param ca root CA file for SSL/TLS connection. + * @param cert cert chain file for SSL/TLS authentication, could be empty + * string. + * @param privkey private key file for SSL/TLS authentication, could be empty + * string. + * @param target_name_override Override the target host name if you want to + * pass multiple address for load balancing with SSL, and there's no DNS. The + * @target_name_override@ must exist in the SANS of your SSL certificate. + * @param arguments user provided grpc channel arguments. + */ + static SyncClient* WithSSL(std::string const& etcd_url, #if defined(WITH_GRPC_CHANNEL_CLASS) - grpc::ChannelArguments const & arguments, + grpc::ChannelArguments const& arguments, #else - grpc_impl::ChannelArguments const & arguments, + grpc_impl::ChannelArguments const& arguments, #endif - std::string const & ca, - std::string const & cert = "", - std::string const & privkey = "", - std::string const & target_name_override = ""); - - ~SyncClient(); - - /** - * Get the HEAD revision of the connected etcd server. - */ - Response head(); - - /** - * Get the value of specified key from the etcd server - * @param key is the key to be read - */ - Response get(std::string const & key); - - /** - * Get the value of specified key of specified revision from the etcd server - * @param key is the key to be read - * @param revision is the revision of the key to be read - */ - Response get(std::string const & key, int64_t revision); - - /** - * Sets the value of a key. The key will be modified if already exists or created - * if it does not exists. - * @param key is the key to be created or modified - * @param value is the new value to be set - */ - Response set(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Sets the value of a key. The key will be modified if already exists or created - * if it does not exists. - * @param key is the key to be created or modified - * @param value is the new value to be set - * @param leaseId is the lease attached to the key - */ - Response set(std::string const & key, std::string const & value, int64_t leaseId); - - /** - * Creates a new key and sets it's value. Fails if the key already exists. - * @param key is the key to be created - * @param value is the value to be set - */ - Response add(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Creates a new key and sets it's value. Fails if the key already exists. - * @param key is the key to be created - * @param value is the value to be set - * @param leaseId is the lease attached to the key - */ - Response add(std::string const & key, std::string const & value, int64_t leaseId); - - /** - * Put a new key-value pair. - * @param key is the key to be put - * @param value is the value to be put - */ - Response put(std::string const & key, std::string const & value); - - /** - * Modifies an existing key. Fails if the key does not exists. - * @param key is the key to be modified - * @param value is the new value to be set - */ - Response modify(std::string const & key, std::string const & value, int ttl = 0); - - /** - * Modifies an existing key. Fails if the key does not exists. - * @param key is the key to be modified - * @param value is the new value to be set - * @param leaseId is the lease attached to the key - */ - Response modify(std::string const & key, std::string const & value, int64_t leaseId); - - /** - * Modifies an existing key only if it has a specific value. Fails if the key does not exists - * or the original value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_value is the value to be replaced - */ - Response modify_if(std::string const & key, std::string const & value, std::string const & old_value, int ttl = 0); - - /** - * Modifies an existing key only if it has a specific value. Fails if the key does not exists - * or the original value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_value is the value to be replaced - * @param leaseId is the lease attached to the key - */ - Response modify_if(std::string const & key, std::string const & value, std::string const & old_value, int64_t leaseId); - - /** - * Modifies an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of the previous value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_index is the expected index of the original value - */ - Response modify_if(std::string const & key, std::string const & value, int64_t old_index, int ttl = 0); - - /** - * Modifies an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of the previous value differs from the expected one. - * @param key is the key to be modified - * @param value is the new value to be set - * @param old_index is the expected index of the original value - * @param leaseId is the lease attached to the key - */ - Response modify_if(std::string const & key, std::string const & value, int64_t old_index, int64_t leaseId); - - /** - * Removes a single key. The key has to point to a plain, non directory entry. - * @param key is the key to be deleted - */ - Response rm(std::string const & key); - - /** - * Removes a single key but only if it has a specific value. Fails if the key does not exists - * or the its value differs from the expected one. - * @param key is the key to be deleted - */ - Response rm_if(std::string const & key, std::string const & old_value); - - /** - * Removes an existing key only if it has a specific modification index value. Fails if the key - * does not exists or the modification index of it differs from the expected one. - * @param key is the key to be deleted - * @param old_index is the expected index of the existing value - */ - Response rm_if(std::string const & key, int64_t old_index); - - /** - * Removes a directory node. Fails if the parent directory dos not exists or not a directory. - * @param key is the directory to be created to be listed - * @param recursive if true then delete a whole subtree, otherwise deletes only an empty directory. - */ - Response rmdir(std::string const & key, bool recursive = false); - - /** - * Removes multiple keys between [key, range_end). - * - * This overload for `const char *` is to avoid const char * to bool implicit casting. - * - * @param key is the directory to be created to be listed - * @param range_end is the end of key range to be removed. - */ - Response rmdir(std::string const & key, const char *range_end); - - /** - * Removes multiple keys between [key, range_end). - * - * @param key is the directory to be created to be listed - * @param range_end is the end of key range to be removed. - */ - Response rmdir(std::string const & key, std::string const &range_end); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * @param key is the key to be listed - */ - Response ls(std::string const & key); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - */ - Response ls(std::string const & key, size_t const limit); - - /** - * Gets a directory listing of the directory prefixed by the key with given revision. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - * @param revision is the revision to be listed - */ - Response ls(std::string const & key, size_t const limit, int64_t revision); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end). - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - */ - Response ls(std::string const & key, std::string const &range_end); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end), and respects the given limit. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - */ - Response ls(std::string const & key, std::string const &range_end, size_t const limit); - - /** - * Gets a directory listing of the directory identified by the key and range_end, i.e., get - * all keys in the range [key, range_end), and respects the given limit and revision. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. 0 means no limit. - * @param revision is the revision to be listed - */ - Response ls(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - */ - Response keys(std::string const & key); - - /** - * Gets a directory listing of the directory prefixed by the key. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - */ - Response keys(std::string const & key, size_t const limit); - - /** - * Gets a directory listing of the directory prefixed by the key with specified revision. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - * @param revision is the revision to be listed - */ - Response keys(std::string const & key, size_t const limit, int64_t revision); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end). - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - */ - Response keys(std::string const & key, std::string const &range_end); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end), and respects the given limit. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - */ - Response keys(std::string const & key, std::string const &range_end, size_t const limit); - - /** - * List keys identified by the key and range_end, i.e., get all keys in the range [key, - * range_end), and respects the given limit and revision. - * - * Note that only keys are included in the response. - * - * @param key is the key to be listed - * @param range_end is the end of key range to be listed - * @param limit is the size limit of results to be listed, we don't use default parameters - * to ensure backwards binary compatibility. - * @param revision is the revision to be listed - */ - Response keys(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision); - - /** - * Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and - * a new key is created, like "/testdir/newkey" then no change happened in the value of - * "/testdir" so your watch will not detect this. If you want to detect addition and deletion of - * directory entries then you have to do a recursive watch. - * @param key is the value or directory to be watched - * @param recursive if true watch a whole subtree - */ - Response watch(std::string const & key, bool recursive = false); - - /** - * Watches for changes of a key or a subtree from a specific index. The index value can be in the "past". - * @param key is the value or directory to be watched - * @param fromIndex the first index we are interested in - * @param recursive if true watch a whole subtree - */ - Response watch(std::string const & key, int64_t fromIndex, bool recursive = false); - - /** - * Watches for changes of a range of keys inside [key, range_end). - * - * This overload for `const char *` is to avoid const char * to bool implicit casting. - * - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - */ - Response watch(std::string const & key, const char *range_end); - - /** - * Watches for changes of a range of keys inside [key, range_end). - * - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - */ - Response watch(std::string const & key, std::string const &range_end); - - /** - * Watches for changes of a range of keys inside [key, range_end) from a specific index. The index value - * can be in the "past". - * - * Watches for changes of a key or a subtree from a specific index. The index value can be in the "past". - * @param key is the value or directory to be watched - * @param range_end is the end of key range to be removed. - * @param fromIndex the first index we are interested in - */ - Response watch(std::string const & key, std::string const &range_end, int64_t fromIndex); - - /** - * Grants a lease. - * @param ttl is the time to live of the lease - */ - Response leasegrant(int ttl); - - /** - * Grants a lease. - * @param ttl is the time to live of the lease - */ - std::shared_ptr leasekeepalive(int ttl); - - /** - * Revoke a lease. - * @param lease_id is the id the lease - */ - Response leaserevoke(int64_t lease_id); - - /** - * Get time-to-live of a lease. - * @param lease_id is the id the lease - */ - Response leasetimetolive(int64_t lease_id); - - /** - * List all alive leases, equivalent to `etcdctl lease list`. - */ - Response leases(); - - /** - * Gains a lock at a key, using a default created lease, using the default lease (10 seconds), with - * keeping alive has already been taken care of by the library. - * @param key is the key to be used to request the lock. - */ - Response lock(std::string const &key); - - /** - * Gains a lock at a key, using a default created lease, using the specified lease TTL (in seconds), with - * keeping alive has already been taken care of by the library. - * @param key is the key to be used to request the lock. - * @param lease_ttl is the TTL used to create a lease for the key. - */ - Response lock(std::string const &key, int lease_ttl); - - /** - * Gains a lock at a key, using a user-provided lease, the lifetime of the lease won't be taken care - * of by the library. - * @param key is the key to be used to request the lock. - */ - Response lock_with_lease(std::string const &key, int64_t lease_id); - - /** - * Releases a lock at a key. - * @param key is the lock key to release. - */ - Response unlock(std::string const &lock_key); - - /** - * Execute a etcd transaction. - * @param txn is the transaction object to be executed. - */ - Response txn(etcdv3::Transaction const &txn); - - /** - * Campaign for the election @name@. - * - * @param name is the name of election that will campaign for. - * @param lease_id is a user-managed (usually with a `KeepAlive`) lease id. - * @param value is the value for campaign. - * - * @returns a leader key if succeed, consist of - * - * - name: the name of the election - * - key: a generated election key - * - created rev: the revision of the generated key - * - lease: the lease id of the election leader - */ - Response campaign(std::string const &name, int64_t lease_id, std::string const &value); - - /** - * Updates the value of election with a new value, with leader key returns by - * @campaign@. - * - * @param name is the name of election - * @param lease_id is the user-provided lease id for the proclamation - * @param key is the generated associated key returned by @campaign@ - * @param revision is the created revision of key-value returned by @campaign@ - * @param value is the new value to set. - */ - Response proclaim(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value); - - /** - * Get the current leader proclamation. - * - * @param name is the names of election. - * - * @returns current election key and value. - */ - Response leader(std::string const &name); - - /** - * An observer that will cancel the associated election::observe request - * when being destruct. - */ - class Observer { - public: - ~Observer(); - // wait at least *one* response from the observer. - Response WaitOnce(); - private: - std::shared_ptr action = nullptr; - - friend class SyncClient; - }; - - /** - * Observe the leader change. - * - * @param name is the names of election to watch. - * - * @returns an observer that holds that action and will cancel the request when being destructed. - */ - std::unique_ptr observe(std::string const &name); - - /** - * Updates the value of election with a new value, with leader key returns by - * @campaign@. - * - * @param name is the name of election - * @param lease_id is the user-provided lease id for the proclamation - * @param key is the generated associated key returned by @campaign@ - * @param revision is the created revision of key-value returned by @campaign@ - */ - Response resign(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision); - - private: - // TODO: use std::unique_ptr<> - std::shared_ptr head_internal(); - std::shared_ptr get_internal(std::string const & key, int64_t revision=0); - std::shared_ptr set_internal(std::string const & key, std::string const & value, int64_t leaseId); - std::shared_ptr add_internal(std::string const & key, std::string const & value, int64_t leaseId); - std::shared_ptr put_internal(std::string const & key, std::string const & value); - std::shared_ptr modify_internal(std::string const & key, std::string const & value, int64_t leaseId); - std::shared_ptr modify_if_internal(std::string const & key, std::string const & value, int64_t old_index, std::string const & old_value, int64_t leaseId, etcdv3::AtomicityType const & atomicity_type); - std::shared_ptr rm_internal(std::string const & key); - std::shared_ptr rm_if_internal(std::string const & key, int64_t old_index, const std::string & old_value, etcdv3::AtomicityType const & atomicity_type); - std::shared_ptr rmdir_internal(std::string const & key, bool recursive = false); - std::shared_ptr rmdir_internal(std::string const & key, std::string const &range_end); - std::shared_ptr ls_internal(std::string const & key, size_t const limit, bool const keys_only = false, int64_t revision=0); - std::shared_ptr ls_internal(std::string const & key, std::string const &range_end, size_t const limit, bool const keys_only = false, int64_t revision=0); - std::shared_ptr watch_internal(std::string const & key, int64_t fromIndex, bool recursive = false); - std::shared_ptr watch_internal(std::string const & key, std::string const &range_end, int64_t fromIndex); - std::shared_ptr leaserevoke_internal(int64_t lease_id); - std::shared_ptr leasetimetolive_internal(int64_t lease_id); - std::shared_ptr leases_internal(); - Response lock_internal(std::string const &key, std::shared_ptr const &keepalive); - std::shared_ptr lock_with_lease_internal(std::string const &key, int64_t lease_id); - std::shared_ptr unlock_internal(std::string const &lock_key); - std::shared_ptr txn_internal(etcdv3::Transaction const &txn); - std::shared_ptr campaign_internal(std::string const &name, int64_t lease_id, std::string const &value); - std::shared_ptr proclaim_internal( - std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value); - std::shared_ptr leader_internal(std::string const &name); - std::shared_ptr resign_internal(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision); - - public: - /** - * Return current auth token. - */ - const std::string ¤t_auth_token() const; - - /** - * Obtain the underlying gRPC channel. - */ + std::string const& ca, + std::string const& cert = "", + std::string const& privkey = "", + std::string const& target_name_override = ""); + + ~SyncClient(); + + /** + * Get the HEAD revision of the connected etcd server. + */ + Response head(); + + /** + * Get the value of specified key from the etcd server + * @param key is the key to be read + */ + Response get(std::string const& key); + + /** + * Get the value of specified key of specified revision from the etcd server + * @param key is the key to be read + * @param revision is the revision of the key to be read + */ + Response get(std::string const& key, int64_t revision); + + /** + * Sets the value of a key. The key will be modified if already exists or + * created if it does not exists. + * @param key is the key to be created or modified + * @param value is the new value to be set + */ + Response set(std::string const& key, std::string const& value, int ttl = 0); + + /** + * Sets the value of a key. The key will be modified if already exists or + * created if it does not exists. + * @param key is the key to be created or modified + * @param value is the new value to be set + * @param leaseId is the lease attached to the key + */ + Response set(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Creates a new key and sets it's value. Fails if the key already exists. + * @param key is the key to be created + * @param value is the value to be set + */ + Response add(std::string const& key, std::string const& value, int ttl = 0); + + /** + * Creates a new key and sets it's value. Fails if the key already exists. + * @param key is the key to be created + * @param value is the value to be set + * @param leaseId is the lease attached to the key + */ + Response add(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Put a new key-value pair. + * @param key is the key to be put + * @param value is the value to be put + */ + Response put(std::string const& key, std::string const& value); + + /** + * Modifies an existing key. Fails if the key does not exists. + * @param key is the key to be modified + * @param value is the new value to be set + */ + Response modify(std::string const& key, std::string const& value, + int ttl = 0); + + /** + * Modifies an existing key. Fails if the key does not exists. + * @param key is the key to be modified + * @param value is the new value to be set + * @param leaseId is the lease attached to the key + */ + Response modify(std::string const& key, std::string const& value, + int64_t leaseId); + + /** + * Modifies an existing key only if it has a specific value. Fails if the key + * does not exists or the original value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_value is the value to be replaced + */ + Response modify_if(std::string const& key, std::string const& value, + std::string const& old_value, int ttl = 0); + + /** + * Modifies an existing key only if it has a specific value. Fails if the key + * does not exists or the original value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_value is the value to be replaced + * @param leaseId is the lease attached to the key + */ + Response modify_if(std::string const& key, std::string const& value, + std::string const& old_value, int64_t leaseId); + + /** + * Modifies an existing key only if it has a specific modification index + * value. Fails if the key does not exists or the modification index of the + * previous value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_index is the expected index of the original value + */ + Response modify_if(std::string const& key, std::string const& value, + int64_t old_index, int ttl = 0); + + /** + * Modifies an existing key only if it has a specific modification index + * value. Fails if the key does not exists or the modification index of the + * previous value differs from the expected one. + * @param key is the key to be modified + * @param value is the new value to be set + * @param old_index is the expected index of the original value + * @param leaseId is the lease attached to the key + */ + Response modify_if(std::string const& key, std::string const& value, + int64_t old_index, int64_t leaseId); + + /** + * Removes a single key. The key has to point to a plain, non directory entry. + * @param key is the key to be deleted + */ + Response rm(std::string const& key); + + /** + * Removes a single key but only if it has a specific value. Fails if the key + * does not exists or the its value differs from the expected one. + * @param key is the key to be deleted + */ + Response rm_if(std::string const& key, std::string const& old_value); + + /** + * Removes an existing key only if it has a specific modification index value. + * Fails if the key does not exists or the modification index of it differs + * from the expected one. + * @param key is the key to be deleted + * @param old_index is the expected index of the existing value + */ + Response rm_if(std::string const& key, int64_t old_index); + + /** + * Removes a directory node. Fails if the parent directory dos not exists or + * not a directory. + * @param key is the directory to be created to be listed + * @param recursive if true then delete a whole subtree, otherwise deletes + * only an empty directory. + */ + Response rmdir(std::string const& key, bool recursive = false); + + /** + * Removes multiple keys between [key, range_end). + * + * This overload for `const char *` is to avoid const char * to bool implicit + * casting. + * + * @param key is the directory to be created to be listed + * @param range_end is the end of key range to be removed. + */ + Response rmdir(std::string const& key, const char* range_end); + + /** + * Removes multiple keys between [key, range_end). + * + * @param key is the directory to be created to be listed + * @param range_end is the end of key range to be removed. + */ + Response rmdir(std::string const& key, std::string const& range_end); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * @param key is the key to be listed + */ + Response ls(std::string const& key); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + */ + Response ls(std::string const& key, size_t const limit); + + /** + * Gets a directory listing of the directory prefixed by the key with given + * revision. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + * @param revision is the revision to be listed + */ + Response ls(std::string const& key, size_t const limit, int64_t revision); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end). + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + */ + Response ls(std::string const& key, std::string const& range_end); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end), and respects + * the given limit. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + */ + Response ls(std::string const& key, std::string const& range_end, + size_t const limit); + + /** + * Gets a directory listing of the directory identified by the key and + * range_end, i.e., get all keys in the range [key, range_end), and respects + * the given limit and revision. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. 0 means no + * limit. + * @param revision is the revision to be listed + */ + Response ls(std::string const& key, std::string const& range_end, + size_t const limit, int64_t revision); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + */ + Response keys(std::string const& key); + + /** + * Gets a directory listing of the directory prefixed by the key. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + */ + Response keys(std::string const& key, size_t const limit); + + /** + * Gets a directory listing of the directory prefixed by the key with + * specified revision. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + * @param revision is the revision to be listed + */ + Response keys(std::string const& key, size_t const limit, int64_t revision); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end). + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + */ + Response keys(std::string const& key, std::string const& range_end); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end), and respects the given limit. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + */ + Response keys(std::string const& key, std::string const& range_end, + size_t const limit); + + /** + * List keys identified by the key and range_end, i.e., get all keys in the + * range [key, range_end), and respects the given limit and revision. + * + * Note that only keys are included in the response. + * + * @param key is the key to be listed + * @param range_end is the end of key range to be listed + * @param limit is the size limit of results to be listed, we don't use + * default parameters to ensure backwards binary compatibility. + * @param revision is the revision to be listed + */ + Response keys(std::string const& key, std::string const& range_end, + size_t const limit, int64_t revision); + + /** + * Watches for changes of a key or a subtree. Please note that if you watch + * e.g. "/testdir" and a new key is created, like "/testdir/newkey" then no + * change happened in the value of + * "/testdir" so your watch will not detect this. If you want to detect + * addition and deletion of directory entries then you have to do a recursive + * watch. + * @param key is the value or directory to be watched + * @param recursive if true watch a whole subtree + */ + Response watch(std::string const& key, bool recursive = false); + + /** + * Watches for changes of a key or a subtree from a specific index. The index + * value can be in the "past". + * @param key is the value or directory to be watched + * @param fromIndex the first index we are interested in + * @param recursive if true watch a whole subtree + */ + Response watch(std::string const& key, int64_t fromIndex, + bool recursive = false); + + /** + * Watches for changes of a range of keys inside [key, range_end). + * + * This overload for `const char *` is to avoid const char * to bool implicit + * casting. + * + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + */ + Response watch(std::string const& key, const char* range_end); + + /** + * Watches for changes of a range of keys inside [key, range_end). + * + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + */ + Response watch(std::string const& key, std::string const& range_end); + + /** + * Watches for changes of a range of keys inside [key, range_end) from a + * specific index. The index value can be in the "past". + * + * Watches for changes of a key or a subtree from a specific index. The index + * value can be in the "past". + * @param key is the value or directory to be watched + * @param range_end is the end of key range to be removed. + * @param fromIndex the first index we are interested in + */ + Response watch(std::string const& key, std::string const& range_end, + int64_t fromIndex); + + /** + * Grants a lease. + * @param ttl is the time to live of the lease + */ + Response leasegrant(int ttl); + + /** + * Grants a lease. + * @param ttl is the time to live of the lease + */ + std::shared_ptr leasekeepalive(int ttl); + + /** + * Revoke a lease. + * @param lease_id is the id the lease + */ + Response leaserevoke(int64_t lease_id); + + /** + * Get time-to-live of a lease. + * @param lease_id is the id the lease + */ + Response leasetimetolive(int64_t lease_id); + + /** + * List all alive leases, equivalent to `etcdctl lease list`. + */ + Response leases(); + + /** + * Gains a lock at a key, using a default created lease, using the default + * lease (10 seconds), with keeping alive has already been taken care of by + * the library. + * @param key is the key to be used to request the lock. + */ + Response lock(std::string const& key); + + /** + * Gains a lock at a key, using a default created lease, using the specified + * lease TTL (in seconds), with keeping alive has already been taken care of + * by the library. + * @param key is the key to be used to request the lock. + * @param lease_ttl is the TTL used to create a lease for the key. + */ + Response lock(std::string const& key, int lease_ttl); + + /** + * Gains a lock at a key, using a user-provided lease, the lifetime of the + * lease won't be taken care of by the library. + * @param key is the key to be used to request the lock. + */ + Response lock_with_lease(std::string const& key, int64_t lease_id); + + /** + * Releases a lock at a key. + * @param key is the lock key to release. + */ + Response unlock(std::string const& lock_key); + + /** + * Execute a etcd transaction. + * @param txn is the transaction object to be executed. + */ + Response txn(etcdv3::Transaction const& txn); + + /** + * Campaign for the election @name@. + * + * @param name is the name of election that will campaign for. + * @param lease_id is a user-managed (usually with a `KeepAlive`) lease id. + * @param value is the value for campaign. + * + * @returns a leader key if succeed, consist of + * + * - name: the name of the election + * - key: a generated election key + * - created rev: the revision of the generated key + * - lease: the lease id of the election leader + */ + Response campaign(std::string const& name, int64_t lease_id, + std::string const& value); + + /** + * Updates the value of election with a new value, with leader key returns by + * @campaign@. + * + * @param name is the name of election + * @param lease_id is the user-provided lease id for the proclamation + * @param key is the generated associated key returned by @campaign@ + * @param revision is the created revision of key-value returned by @campaign@ + * @param value is the new value to set. + */ + Response proclaim(std::string const& name, int64_t lease_id, + std::string const& key, int64_t revision, + std::string const& value); + + /** + * Get the current leader proclamation. + * + * @param name is the names of election. + * + * @returns current election key and value. + */ + Response leader(std::string const& name); + + /** + * An observer that will cancel the associated election::observe request + * when being destruct. + */ + class Observer { + public: + ~Observer(); + // wait at least *one* response from the observer. + Response WaitOnce(); + + private: + std::shared_ptr action = nullptr; + + friend class SyncClient; + }; + + /** + * Observe the leader change. + * + * @param name is the names of election to watch. + * + * @returns an observer that holds that action and will cancel the request + * when being destructed. + */ + std::unique_ptr observe(std::string const& name); + + /** + * Updates the value of election with a new value, with leader key returns by + * @campaign@. + * + * @param name is the name of election + * @param lease_id is the user-provided lease id for the proclamation + * @param key is the generated associated key returned by @campaign@ + * @param revision is the created revision of key-value returned by @campaign@ + */ + Response resign(std::string const& name, int64_t lease_id, + std::string const& key, int64_t revision); + + private: + // TODO: use std::unique_ptr<> + std::shared_ptr head_internal(); + std::shared_ptr get_internal(std::string const& key, + int64_t revision = 0); + std::shared_ptr set_internal(std::string const& key, + std::string const& value, + int64_t leaseId); + std::shared_ptr add_internal(std::string const& key, + std::string const& value, + int64_t leaseId); + std::shared_ptr put_internal( + std::string const& key, std::string const& value); + std::shared_ptr modify_internal( + std::string const& key, std::string const& value, int64_t leaseId); + std::shared_ptr modify_if_internal( + std::string const& key, std::string const& value, int64_t old_index, + std::string const& old_value, int64_t leaseId, + etcdv3::AtomicityType const& atomicity_type); + std::shared_ptr rm_internal( + std::string const& key); + std::shared_ptr rm_if_internal( + std::string const& key, int64_t old_index, const std::string& old_value, + etcdv3::AtomicityType const& atomicity_type); + std::shared_ptr rmdir_internal( + std::string const& key, bool recursive = false); + std::shared_ptr rmdir_internal( + std::string const& key, std::string const& range_end); + std::shared_ptr ls_internal( + std::string const& key, size_t const limit, bool const keys_only = false, + int64_t revision = 0); + std::shared_ptr ls_internal( + std::string const& key, std::string const& range_end, size_t const limit, + bool const keys_only = false, int64_t revision = 0); + std::shared_ptr watch_internal( + std::string const& key, int64_t fromIndex, bool recursive = false); + std::shared_ptr watch_internal( + std::string const& key, std::string const& range_end, int64_t fromIndex); + std::shared_ptr leaserevoke_internal( + int64_t lease_id); + std::shared_ptr leasetimetolive_internal( + int64_t lease_id); + std::shared_ptr leases_internal(); + Response lock_internal(std::string const& key, + std::shared_ptr const& keepalive); + std::shared_ptr lock_with_lease_internal( + std::string const& key, int64_t lease_id); + std::shared_ptr unlock_internal( + std::string const& lock_key); + std::shared_ptr txn_internal( + etcdv3::Transaction const& txn); + std::shared_ptr campaign_internal( + std::string const& name, int64_t lease_id, std::string const& value); + std::shared_ptr proclaim_internal( + std::string const& name, int64_t lease_id, std::string const& key, + int64_t revision, std::string const& value); + std::shared_ptr leader_internal( + std::string const& name); + std::shared_ptr resign_internal( + std::string const& name, int64_t lease_id, std::string const& key, + int64_t revision); + + public: + /** + * Return current auth token. + */ + const std::string& current_auth_token() const; + + /** + * Obtain the underlying gRPC channel. + */ #if defined(WITH_GRPC_CHANNEL_CLASS) - std::shared_ptr grpc_channel() const; + std::shared_ptr grpc_channel() const; #else - std::shared_ptr grpc_channel() const; + std::shared_ptr grpc_channel() const; #endif - /** - * Set a timeout value for grpc operations. - */ - template - void set_grpc_timeout(std::chrono::duration const &timeout) { - grpc_timeout = std::chrono::duration_cast(timeout); - } - - /** - * Get the current timeout value for grpc operations. - */ - std::chrono::microseconds get_grpc_timeout() const { - return this->grpc_timeout; - } - - private: + /** + * Set a timeout value for grpc operations. + */ + template + void set_grpc_timeout(std::chrono::duration const& timeout) { + grpc_timeout = + std::chrono::duration_cast(timeout); + } + + /** + * Get the current timeout value for grpc operations. + */ + std::chrono::microseconds get_grpc_timeout() const { + return this->grpc_timeout; + } + + private: #if defined(WITH_GRPC_CHANNEL_CLASS) - std::shared_ptr channel; + std::shared_ptr channel; #else - std::shared_ptr channel; + std::shared_ptr channel; #endif - mutable std::unique_ptr token_authenticator; - mutable std::chrono::microseconds grpc_timeout = std::chrono::microseconds::zero(); + mutable std::unique_ptr + token_authenticator; + mutable std::chrono::microseconds grpc_timeout = + std::chrono::microseconds::zero(); - struct EtcdServerStubs; - struct EtcdServerStubsDeleter { - void operator()(EtcdServerStubs *stubs); - }; - std::unique_ptr stubs; + struct EtcdServerStubs; + struct EtcdServerStubsDeleter { + void operator()(EtcdServerStubs* stubs); + }; + std::unique_ptr stubs; - std::mutex mutex_for_keepalives; - std::map leases_for_locks; - std::map> keep_alive_for_locks; + std::mutex mutex_for_keepalives; + std::map leases_for_locks; + std::map> keep_alive_for_locks; - friend class KeepAlive; - friend class Watcher; - friend class Client; + friend class KeepAlive; + friend class Watcher; + friend class Client; }; -} +} // namespace etcd #endif diff --git a/etcd/Value.hpp b/etcd/Value.hpp index c3befef..46f684b 100644 --- a/etcd/Value.hpp +++ b/etcd/Value.hpp @@ -5,126 +5,124 @@ #include namespace etcdv3 { - class KeyValue; +class KeyValue; } namespace mvccpb { - class KeyValue; - class Event; -} +class KeyValue; +class Event; +} // namespace mvccpb namespace electionpb { - class LeaderKey; +class LeaderKey; } -namespace etcd -{ - class Value; - class Event; - class Response; - class Client; - class SyncClient; +namespace etcd { +class Value; +class Event; +class Response; +class Client; +class SyncClient; + +/** + * Represents a value object received from the etcd server + */ +class Value { + public: + /** + * Returns true if this value represents a directory on the server. If true + * the as_string() method is meaningless. + */ + bool is_dir() const; /** - * Represents a value object received from the etcd server + * Returns the key of this value as an "absolute path". */ - class Value - { - public: - /** - * Returns true if this value represents a directory on the server. If true the as_string() - * method is meaningless. - */ - bool is_dir() const; - - /** - * Returns the key of this value as an "absolute path". - */ - std::string const & key() const; - - /** - * Returns the string representation of the value - */ - std::string const & as_string() const; - - /** - * Returns the creation index of this value. - */ - int64_t created_index() const; - - /** - * Returns the last modification's index of this value. - */ - int64_t modified_index() const; - - /** - * Returns the version of this value. - */ - int64_t version() const; - - /** - * Returns the ttl of this value or 0 if ttl is not set - */ - int ttl() const; - - int64_t lease() const; - - protected: - friend class Client; - friend class SyncClient; - friend class Response; - friend class BaseResponse; //deliberately done since Value class will be removed during full V3 - friend class DeleteRpcResponse; - friend class AsyncDeleteResponse; - - friend class Event; - - Value(); - Value(etcdv3::KeyValue const & kvs); - Value(mvccpb::KeyValue const & kvs); - std::string _key; - bool dir; - std::string value; - int64_t created; - int64_t modified; - int64_t _version; - int _ttl; - int64_t leaseId; - }; + std::string const& key() const; + + /** + * Returns the string representation of the value + */ + std::string const& as_string() const; + + /** + * Returns the creation index of this value. + */ + int64_t created_index() const; - typedef std::vector Values; + /** + * Returns the last modification's index of this value. + */ + int64_t modified_index() const; + + /** + * Returns the version of this value. + */ + int64_t version() const; - class Event - { - public: - enum class EventType { - PUT, - DELETE_, - INVALID, - }; + /** + * Returns the ttl of this value or 0 if ttl is not set + */ + int ttl() const; + + int64_t lease() const; + + protected: + friend class Client; + friend class SyncClient; + friend class Response; + friend class BaseResponse; // deliberately done since Value class will be + // removed during full V3 + friend class DeleteRpcResponse; + friend class AsyncDeleteResponse; + + friend class Event; + + Value(); + Value(etcdv3::KeyValue const& kvs); + Value(mvccpb::KeyValue const& kvs); + std::string _key; + bool dir; + std::string value; + int64_t created; + int64_t modified; + int64_t _version; + int _ttl; + int64_t leaseId; +}; + +typedef std::vector Values; + +class Event { + public: + enum class EventType { + PUT, + DELETE_, + INVALID, + }; - enum EventType event_type() const; + enum EventType event_type() const; - bool has_kv() const; + bool has_kv() const; - bool has_prev_kv() const; + bool has_prev_kv() const; - const Value &kv() const; + const Value& kv() const; - const Value &prev_kv() const; + const Value& prev_kv() const; - protected: - friend class Response; + protected: + friend class Response; - Event(mvccpb::Event const & event); + Event(mvccpb::Event const& event); - private: - enum EventType event_type_; - Value _kv, _prev_kv; - bool _has_kv, _has_prev_kv; - }; + private: + enum EventType event_type_; + Value _kv, _prev_kv; + bool _has_kv, _has_prev_kv; +}; - typedef std::vector Events; -} +typedef std::vector Events; +} // namespace etcd #endif diff --git a/etcd/Watcher.hpp b/etcd/Watcher.hpp index 2f66099..95a943d 100644 --- a/etcd/Watcher.hpp +++ b/etcd/Watcher.hpp @@ -8,237 +8,199 @@ #include "etcd/Response.hpp" -namespace etcd -{ - // forward declaration to avoid header/library dependency - class Client; - - class Watcher - { - public: - Watcher(Client const &client, std::string const & key, - std::function callback, - bool recursive=false); - Watcher(SyncClient const &client, std::string const & key, - std::function callback, - bool recursive=false); - Watcher(Client const &client, std::string const & key, - std::string const &range_end, - std::function callback); - Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, - std::function callback); - Watcher(Client const &client, std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive=false); - Watcher(SyncClient const &client, std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive=false); - Watcher(Client const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback); - Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback); - Watcher(std::string const & address, std::string const & key, - std::function callback, - bool recursive=false); - Watcher(std::string const & address, std::string const & key, - std::string const &range_end, - std::function callback); - Watcher(std::string const & address, std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive=false); - Watcher(std::string const & address, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, - std::function callback, - bool recursive=false, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, - std::function callback, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive=false, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, int64_t fromIndex, - std::function callback, bool recursive=false, - std::string const & target_name_override = ""); - Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - std::string const & target_name_override = ""); - - Watcher(Client const &client, std::string const & key, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(SyncClient const &client, std::string const & key, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(Client const &client, std::string const & key, - std::string const &range_end, - std::function callback, - std::function wait_callback); - Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, - std::function callback, - std::function wait_callback); - Watcher(Client const &client, std::string const & key, int64_t fromIndex, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(SyncClient const &client, std::string const & key, int64_t fromIndex, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(Client const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback, - std::function wait_callback); - Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback, - std::function wait_callback); - Watcher(std::string const & address, std::string const & key, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(std::string const & address, std::string const & key, - std::string const &range_end, - std::function callback, - std::function wait_callback); - Watcher(std::string const & address, std::string const & key, int64_t fromIndex, - std::function callback, - std::function wait_callback, - bool recursive=false); - Watcher(std::string const & address, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback, - std::function wait_callback); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, - std::function callback, - std::function wait_callback, - bool recursive=false, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, - std::function callback, - std::function wait_callback, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, int64_t fromIndex, - std::function callback, - std::function wait_callback, - bool recursive=false, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - std::function wait_callback, - int const auth_token_ttl = 300); - Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, int64_t fromIndex, - std::function callback, - std::function wait_callback, - bool recursive=false, - std::string const & target_name_override = ""); - Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - std::function wait_callback, - std::string const & target_name_override = ""); - - Watcher(Watcher const &) = delete; - Watcher(Watcher &&) = delete; - - /** - * Wait util the task has been stopped, actively or passively, e.g., the watcher - * get cancelled or the server closes the connection. - * - * Returns true if the watcher is been normally cancelled, otherwise false. - */ - bool Wait(); - - /** - * An async wait, the callback will be called when the task has been stopped. - * - * The callback parameter would be true if the watch is been normally cancelled. - * - * Note that you shouldn't use the watcher itself inside the `Wait()` callback - * as the callback will be invoked in a separate **detached** thread where the - * watcher may have been destroyed. - */ - void Wait(std::function callback); - - /** - * Stop the watching action. - */ - bool Cancel(); - - /** - * Whether the watcher has been cancelled. - */ - bool Cancelled() const; - - ~Watcher(); - - protected: - void doWatch(std::string const & key, - std::string const & range_end, - std::string const & auth_token, - std::function callback); - - std::function callback; - std::function wait_callback; - - // Don't use `pplx::task` to avoid sharing thread pool with other actions on the client - // to avoid any potential blocking, which may block the keepalive loop and evict the lease. - std::thread task_; - - struct EtcdServerStubs; - struct EtcdServerStubsDeleter { - void operator()(etcd::Watcher::EtcdServerStubs *stubs); - }; - std::unique_ptr stubs; - - private: - int64_t fromIndex; - bool recursive; - std::atomic_bool cancelled; +namespace etcd { +// forward declaration to avoid header/library dependency +class Client; + +class Watcher { + public: + Watcher(Client const& client, std::string const& key, + std::function callback, bool recursive = false); + Watcher(SyncClient const& client, std::string const& key, + std::function callback, bool recursive = false); + Watcher(Client const& client, std::string const& key, + std::string const& range_end, std::function callback); + Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, std::function callback); + Watcher(Client const& client, std::string const& key, int64_t fromIndex, + std::function callback, bool recursive = false); + Watcher(SyncClient const& client, std::string const& key, int64_t fromIndex, + std::function callback, bool recursive = false); + Watcher(Client const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback); + Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback); + Watcher(std::string const& address, std::string const& key, + std::function callback, bool recursive = false); + Watcher(std::string const& address, std::string const& key, + std::string const& range_end, std::function callback); + Watcher(std::string const& address, std::string const& key, int64_t fromIndex, + std::function callback, bool recursive = false); + Watcher(std::string const& address, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::function callback, bool recursive = false, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, std::function callback, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + int64_t fromIndex, std::function callback, + bool recursive = false, int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, int64_t fromIndex, + std::function callback, bool recursive = false, + std::string const& target_name_override = ""); + Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, std::string const& range_end, + int64_t fromIndex, std::function callback, + std::string const& target_name_override = ""); + + Watcher(Client const& client, std::string const& key, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(SyncClient const& client, std::string const& key, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(Client const& client, std::string const& key, + std::string const& range_end, std::function callback, + std::function wait_callback); + Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, std::function callback, + std::function wait_callback); + Watcher(Client const& client, std::string const& key, int64_t fromIndex, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(SyncClient const& client, std::string const& key, int64_t fromIndex, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(Client const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback, + std::function wait_callback); + Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback, + std::function wait_callback); + Watcher(std::string const& address, std::string const& key, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(std::string const& address, std::string const& key, + std::string const& range_end, std::function callback, + std::function wait_callback); + Watcher(std::string const& address, std::string const& key, int64_t fromIndex, + std::function callback, + std::function wait_callback, bool recursive = false); + Watcher(std::string const& address, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback, + std::function wait_callback); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::function callback, + std::function wait_callback, bool recursive = false, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, std::function callback, + std::function wait_callback, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + int64_t fromIndex, std::function callback, + std::function wait_callback, bool recursive = false, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback, + std::function wait_callback, + int const auth_token_ttl = 300); + Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, int64_t fromIndex, + std::function callback, + std::function wait_callback, bool recursive = false, + std::string const& target_name_override = ""); + Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, std::string const& range_end, + int64_t fromIndex, std::function callback, + std::function wait_callback, + std::string const& target_name_override = ""); + + Watcher(Watcher const&) = delete; + Watcher(Watcher&&) = delete; + + /** + * Wait util the task has been stopped, actively or passively, e.g., the + * watcher get cancelled or the server closes the connection. + * + * Returns true if the watcher is been normally cancelled, otherwise false. + */ + bool Wait(); + + /** + * An async wait, the callback will be called when the task has been stopped. + * + * The callback parameter would be true if the watch is been normally + * cancelled. + * + * Note that you shouldn't use the watcher itself inside the `Wait()` callback + * as the callback will be invoked in a separate **detached** thread where the + * watcher may have been destroyed. + */ + void Wait(std::function callback); + + /** + * Stop the watching action. + */ + bool Cancel(); + + /** + * Whether the watcher has been cancelled. + */ + bool Cancelled() const; + + ~Watcher(); + + protected: + void doWatch(std::string const& key, std::string const& range_end, + std::string const& auth_token, + std::function callback); + + std::function callback; + std::function wait_callback; + + // Don't use `pplx::task` to avoid sharing thread pool with other actions on + // the client to avoid any potential blocking, which may block the keepalive + // loop and evict the lease. + std::thread task_; + + struct EtcdServerStubs; + struct EtcdServerStubsDeleter { + void operator()(etcd::Watcher::EtcdServerStubs* stubs); }; -} + std::unique_ptr stubs; + + private: + int64_t fromIndex; + bool recursive; + std::atomic_bool cancelled; +}; +} // namespace etcd #endif diff --git a/etcd/v3/Action.hpp b/etcd/v3/Action.hpp index ee2f550..1920758 100644 --- a/etcd/v3/Action.hpp +++ b/etcd/v3/Action.hpp @@ -6,86 +6,81 @@ #include #include "proto/rpc.grpc.pb.h" -#include "proto/v3lock.grpc.pb.h" #include "proto/v3election.grpc.pb.h" +#include "proto/v3lock.grpc.pb.h" using grpc::ClientContext; using grpc::CompletionQueue; using grpc::Status; using etcdserverpb::KV; -using etcdserverpb::Watch; using etcdserverpb::Lease; -using v3lockpb::Lock; +using etcdserverpb::Watch; using v3electionpb::Election; +using v3lockpb::Lock; namespace etcd { - class Response; +class Response; } -namespace etcdv3 -{ - enum class AtomicityType - { - PREV_INDEX = 0, - PREV_VALUE = 1 - }; +namespace etcdv3 { +enum class AtomicityType { PREV_INDEX = 0, PREV_VALUE = 1 }; - struct ActionParameters - { - ActionParameters(); - bool withPrefix; - int64_t revision = 0; - int64_t old_revision = 0; - int64_t lease_id = 0; // no lease - int ttl; - int limit; - std::string name; // for campaign (in v3election) - std::string key; - std::string range_end; - bool keys_only; - bool count_only; - std::string value; - std::string old_value; - std::string auth_token; - std::chrono::microseconds grpc_timeout = std::chrono::microseconds::zero(); - KV::Stub* kv_stub; - Watch::Stub* watch_stub; - Lease::Stub* lease_stub; - Lock::Stub* lock_stub; - Election::Stub* election_stub; +struct ActionParameters { + ActionParameters(); + bool withPrefix; + int64_t revision = 0; + int64_t old_revision = 0; + int64_t lease_id = 0; // no lease + int ttl; + int limit; + std::string name; // for campaign (in v3election) + std::string key; + std::string range_end; + bool keys_only; + bool count_only; + std::string value; + std::string old_value; + std::string auth_token; + std::chrono::microseconds grpc_timeout = std::chrono::microseconds::zero(); + KV::Stub* kv_stub; + Watch::Stub* watch_stub; + Lease::Stub* lease_stub; + Lock::Stub* lock_stub; + Election::Stub* election_stub; - bool has_grpc_timeout() const; - std::chrono::system_clock::time_point grpc_deadline() const; + bool has_grpc_timeout() const; + std::chrono::system_clock::time_point grpc_deadline() const; - void dump(std::ostream &os) const; - }; + void dump(std::ostream& os) const; +}; - class Action - { - public: - Action(etcdv3::ActionParameters const ¶ms); - Action(etcdv3::ActionParameters && params); - virtual ~Action(); +class Action { + public: + Action(etcdv3::ActionParameters const& params); + Action(etcdv3::ActionParameters&& params); + virtual ~Action(); - void waitForResponse(); - const std::chrono::high_resolution_clock::time_point startTimepoint(); - protected: - Status status; - ClientContext context; - CompletionQueue cq_; - etcdv3::ActionParameters parameters; - std::chrono::high_resolution_clock::time_point start_timepoint; - private: - // Init things like auth token, etc. - void InitAction(); + void waitForResponse(); + const std::chrono::high_resolution_clock::time_point startTimepoint(); - friend class etcd::Response; - }; + protected: + Status status; + ClientContext context; + CompletionQueue cq_; + etcdv3::ActionParameters parameters; + std::chrono::high_resolution_clock::time_point start_timepoint; - namespace detail { - std::string string_plus_one(std::string const &value); - std::string resolve_etcd_endpoints(std::string const &default_endpoints); - } -} + private: + // Init things like auth token, etc. + void InitAction(); + + friend class etcd::Response; +}; + +namespace detail { +std::string string_plus_one(std::string const& value); +std::string resolve_etcd_endpoints(std::string const& default_endpoints); +} // namespace detail +} // namespace etcdv3 #endif diff --git a/etcd/v3/AsyncGRPC.hpp b/etcd/v3/AsyncGRPC.hpp index 8533c28..901f7a2 100644 --- a/etcd/v3/AsyncGRPC.hpp +++ b/etcd/v3/AsyncGRPC.hpp @@ -6,16 +6,16 @@ #include -#include "proto/rpc.pb.h" #include "proto/rpc.grpc.pb.h" -#include "proto/v3election.pb.h" +#include "proto/rpc.pb.h" #include "proto/v3election.grpc.pb.h" -#include "proto/v3lock.pb.h" +#include "proto/v3election.pb.h" #include "proto/v3lock.grpc.pb.h" +#include "proto/v3lock.pb.h" +#include "etcd/Response.hpp" #include "etcd/v3/Action.hpp" #include "etcd/v3/V3Response.hpp" -#include "etcd/Response.hpp" using grpc::ClientAsyncReader; using grpc::ClientAsyncReaderWriter; @@ -23,28 +23,20 @@ using grpc::ClientAsyncResponseReader; using etcdserverpb::KV; -using v3electionpb::CampaignRequest; -using v3electionpb::CampaignResponse; using etcdserverpb::DeleteRangeRequest; using etcdserverpb::DeleteRangeResponse; using etcdserverpb::LeaseCheckpointRequest; using etcdserverpb::LeaseCheckpointResponse; using etcdserverpb::LeaseGrantRequest; using etcdserverpb::LeaseGrantResponse; -using etcdserverpb::LeaseRevokeRequest; -using etcdserverpb::LeaseRevokeResponse; using etcdserverpb::LeaseKeepAliveRequest; using etcdserverpb::LeaseKeepAliveResponse; using etcdserverpb::LeaseLeasesRequest; using etcdserverpb::LeaseLeasesResponse; +using etcdserverpb::LeaseRevokeRequest; +using etcdserverpb::LeaseRevokeResponse; using etcdserverpb::LeaseTimeToLiveRequest; using etcdserverpb::LeaseTimeToLiveResponse; -using etcdserverpb::TxnRequest; -using etcdserverpb::TxnResponse; -using etcdserverpb::RangeRequest; -using etcdserverpb::RangeResponse; -using v3electionpb::ResignRequest; -using v3electionpb::ResignResponse; using etcdserverpb::PutRequest; using etcdserverpb::PutResponse; using etcdserverpb::RangeRequest; @@ -53,393 +45,393 @@ using etcdserverpb::TxnRequest; using etcdserverpb::TxnResponse; using etcdserverpb::WatchRequest; using etcdserverpb::WatchResponse; +using v3electionpb::CampaignRequest; +using v3electionpb::CampaignResponse; using v3electionpb::LeaderRequest; using v3electionpb::LeaderResponse; using v3electionpb::ProclaimRequest; using v3electionpb::ProclaimResponse; +using v3electionpb::ResignRequest; +using v3electionpb::ResignResponse; using v3lockpb::LockRequest; using v3lockpb::LockResponse; using v3lockpb::UnlockRequest; using v3lockpb::UnlockResponse; namespace etcd { - class KeepAlive; +class KeepAlive; } namespace etcdv3 { - class Transaction; +class Transaction; } namespace etcdv3 { - class AsyncCampaignResponse : public etcdv3::V3Response - { - public: - AsyncCampaignResponse(){}; - void ParseResponse(CampaignResponse& resp); - }; - - class AsyncDeleteResponse : public etcdv3::V3Response - { - public: - AsyncDeleteResponse(){}; - void ParseResponse(std::string const& key, bool prefix, DeleteRangeResponse& resp); - }; - - class AsyncHeadResponse : public etcdv3::V3Response - { - public: - AsyncHeadResponse(){}; - void ParseResponse(RangeResponse& resp); - }; - - class AsyncLeaderResponse : public etcdv3::V3Response - { - public: - AsyncLeaderResponse(){}; - void ParseResponse(LeaderResponse& resp); - }; - - class AsyncLeaseGrantResponse : public etcdv3::V3Response - { - public: - AsyncLeaseGrantResponse(){}; - void ParseResponse(LeaseGrantResponse& resp); - }; - - class AsyncLeaseKeepAliveResponse : public etcdv3::V3Response - { - public: - AsyncLeaseKeepAliveResponse(){}; - void ParseResponse(LeaseKeepAliveResponse& resp); - }; - - class AsyncLeaseLeasesResponse : public etcdv3::V3Response - { - public: - AsyncLeaseLeasesResponse(){}; - void ParseResponse(LeaseLeasesResponse& resp); - }; - - class AsyncLeaseRevokeResponse : public etcdv3::V3Response - { - public: - AsyncLeaseRevokeResponse(){}; - void ParseResponse(LeaseRevokeResponse& resp); - }; - - class AsyncLeaseTimeToLiveResponse : public etcdv3::V3Response - { - public: - AsyncLeaseTimeToLiveResponse(){}; - void ParseResponse(LeaseTimeToLiveResponse& resp); - }; - - class AsyncLockResponse : public etcdv3::V3Response - { - public: - AsyncLockResponse(){}; - void ParseResponse(LockResponse& resp); - }; - - class AsyncObserveResponse : public etcdv3::V3Response - { - public: - AsyncObserveResponse(){}; - void ParseResponse(LeaderResponse& resp); - }; - - class AsyncProclaimResponse : public etcdv3::V3Response - { - public: - AsyncProclaimResponse(){}; - void ParseResponse(ProclaimResponse& resp); - }; - - class AsyncPutResponse : public etcdv3::V3Response - { - public: - AsyncPutResponse(){}; - void ParseResponse(PutResponse& resp); - }; - - class AsyncRangeResponse : public etcdv3::V3Response - { - public: - AsyncRangeResponse(){}; - void ParseResponse(RangeResponse& resp, bool prefix=false); - }; - - class AsyncResignResponse : public etcdv3::V3Response - { - public: - AsyncResignResponse(){}; - void ParseResponse(ResignResponse& resp); - }; - - class AsyncTxnResponse : public etcdv3::V3Response - { - public: - AsyncTxnResponse(){}; - void ParseResponse(TxnResponse& resp); - void ParseResponse(std::string const& key, bool prefix, TxnResponse& resp); - }; - - class AsyncUnlockResponse : public etcdv3::V3Response - { - public: - AsyncUnlockResponse(){}; - void ParseResponse(UnlockResponse& resp); - }; - - class AsyncWatchResponse : public etcdv3::V3Response - { - public: - AsyncWatchResponse(){}; - void ParseResponse(WatchResponse& resp); - }; -} +class AsyncCampaignResponse : public etcdv3::V3Response { + public: + AsyncCampaignResponse(){}; + void ParseResponse(CampaignResponse& resp); +}; + +class AsyncDeleteResponse : public etcdv3::V3Response { + public: + AsyncDeleteResponse(){}; + void ParseResponse(std::string const& key, bool prefix, + DeleteRangeResponse& resp); +}; + +class AsyncHeadResponse : public etcdv3::V3Response { + public: + AsyncHeadResponse(){}; + void ParseResponse(RangeResponse& resp); +}; + +class AsyncLeaderResponse : public etcdv3::V3Response { + public: + AsyncLeaderResponse(){}; + void ParseResponse(LeaderResponse& resp); +}; + +class AsyncLeaseGrantResponse : public etcdv3::V3Response { + public: + AsyncLeaseGrantResponse(){}; + void ParseResponse(LeaseGrantResponse& resp); +}; + +class AsyncLeaseKeepAliveResponse : public etcdv3::V3Response { + public: + AsyncLeaseKeepAliveResponse(){}; + void ParseResponse(LeaseKeepAliveResponse& resp); +}; + +class AsyncLeaseLeasesResponse : public etcdv3::V3Response { + public: + AsyncLeaseLeasesResponse(){}; + void ParseResponse(LeaseLeasesResponse& resp); +}; + +class AsyncLeaseRevokeResponse : public etcdv3::V3Response { + public: + AsyncLeaseRevokeResponse(){}; + void ParseResponse(LeaseRevokeResponse& resp); +}; + +class AsyncLeaseTimeToLiveResponse : public etcdv3::V3Response { + public: + AsyncLeaseTimeToLiveResponse(){}; + void ParseResponse(LeaseTimeToLiveResponse& resp); +}; + +class AsyncLockResponse : public etcdv3::V3Response { + public: + AsyncLockResponse(){}; + void ParseResponse(LockResponse& resp); +}; + +class AsyncObserveResponse : public etcdv3::V3Response { + public: + AsyncObserveResponse(){}; + void ParseResponse(LeaderResponse& resp); +}; + +class AsyncProclaimResponse : public etcdv3::V3Response { + public: + AsyncProclaimResponse(){}; + void ParseResponse(ProclaimResponse& resp); +}; + +class AsyncPutResponse : public etcdv3::V3Response { + public: + AsyncPutResponse(){}; + void ParseResponse(PutResponse& resp); +}; + +class AsyncRangeResponse : public etcdv3::V3Response { + public: + AsyncRangeResponse(){}; + void ParseResponse(RangeResponse& resp, bool prefix = false); +}; + +class AsyncResignResponse : public etcdv3::V3Response { + public: + AsyncResignResponse(){}; + void ParseResponse(ResignResponse& resp); +}; + +class AsyncTxnResponse : public etcdv3::V3Response { + public: + AsyncTxnResponse(){}; + void ParseResponse(TxnResponse& resp); + void ParseResponse(std::string const& key, bool prefix, TxnResponse& resp); +}; + +class AsyncUnlockResponse : public etcdv3::V3Response { + public: + AsyncUnlockResponse(){}; + void ParseResponse(UnlockResponse& resp); +}; + +class AsyncWatchResponse : public etcdv3::V3Response { + public: + AsyncWatchResponse(){}; + void ParseResponse(WatchResponse& resp); +}; +} // namespace etcdv3 -namespace etcdv3 -{ - class AsyncCampaignAction : public etcdv3::Action - { - public: - AsyncCampaignAction(etcdv3::ActionParameters && params); - AsyncCampaignResponse ParseResponse(); - private: - CampaignResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncCompareAndDeleteAction : public etcdv3::Action - { - public: - AsyncCompareAndDeleteAction(etcdv3::ActionParameters && params, etcdv3::AtomicityType type); - AsyncTxnResponse ParseResponse(); - private: - TxnResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncCompareAndSwapAction : public etcdv3::Action - { - public: - AsyncCompareAndSwapAction(etcdv3::ActionParameters && params, etcdv3::AtomicityType type); - AsyncTxnResponse ParseResponse(); - private: - TxnResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncDeleteAction : public etcdv3::Action - { - public: - AsyncDeleteAction(etcdv3::ActionParameters && params); - AsyncDeleteResponse ParseResponse(); - private: - DeleteRangeResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncHeadAction : public etcdv3::Action - { - public: - AsyncHeadAction(etcdv3::ActionParameters && params); - AsyncHeadResponse ParseResponse(); - private: - RangeResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLeaderAction : public etcdv3::Action - { - public: - AsyncLeaderAction(etcdv3::ActionParameters && params); - AsyncLeaderResponse ParseResponse(); - private: - LeaderResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLeaseGrantAction : public etcdv3::Action { - public: - AsyncLeaseGrantAction(etcdv3::ActionParameters && params); - AsyncLeaseGrantResponse ParseResponse(); - private: - LeaseGrantResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLeaseKeepAliveAction: public etcdv3::Action { - public: - AsyncLeaseKeepAliveAction(etcdv3::ActionParameters && params); - AsyncLeaseKeepAliveResponse ParseResponse(); - - etcd::Response Refresh(); - void CancelKeepAlive(); - bool Cancelled() const; - - private: - etcdv3::ActionParameters& mutable_parameters(); - - LeaseKeepAliveResponse reply; - std::unique_ptr> stream; - - LeaseKeepAliveRequest req; - bool isCancelled; - std::recursive_mutex protect_is_cancelled; - - friend class etcd::KeepAlive; - }; - - class AsyncLeaseLeasesAction: public etcdv3::Action { - public: - AsyncLeaseLeasesAction(etcdv3::ActionParameters && params); - AsyncLeaseLeasesResponse ParseResponse(); - private: - LeaseLeasesResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLeaseRevokeAction: public etcdv3::Action { - public: - AsyncLeaseRevokeAction(etcdv3::ActionParameters && params); - AsyncLeaseRevokeResponse ParseResponse(); - private: - LeaseRevokeResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLeaseTimeToLiveAction: public etcdv3::Action { - public: - AsyncLeaseTimeToLiveAction(etcdv3::ActionParameters && params); - AsyncLeaseTimeToLiveResponse ParseResponse(); - private: - LeaseTimeToLiveResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncLockAction : public etcdv3::Action - { - public: - AsyncLockAction(etcdv3::ActionParameters && params); - AsyncLockResponse ParseResponse(); - private: - LockResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncObserveAction : public etcdv3::Action - { - public: - AsyncObserveAction(etcdv3::ActionParameters && params); - AsyncObserveResponse ParseResponse(); - void waitForResponse(); - void CancelObserve(); - bool Cancelled() const; - private: - LeaderResponse reply; - std::unique_ptr> response_reader; - std::atomic_bool isCancelled; - std::mutex protect_is_cancalled; - }; - - class AsyncProclaimAction : public etcdv3::Action - { - public: - AsyncProclaimAction(etcdv3::ActionParameters && params); - AsyncProclaimResponse ParseResponse(); - private: - ProclaimResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncPutAction : public etcdv3::Action - { - public: - AsyncPutAction(etcdv3::ActionParameters && params); - AsyncPutResponse ParseResponse(); - private: - PutResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncRangeAction : public etcdv3::Action - { - public: - AsyncRangeAction(etcdv3::ActionParameters && params); - AsyncRangeResponse ParseResponse(); - private: - RangeResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncResignAction : public etcdv3::Action - { - public: - AsyncResignAction(etcdv3::ActionParameters && params); - AsyncResignResponse ParseResponse(); - private: - ResignResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncSetAction : public etcdv3::Action - { - public: - AsyncSetAction(etcdv3::ActionParameters && params, bool create=false); - AsyncTxnResponse ParseResponse(); - private: - TxnResponse reply; - std::unique_ptr> response_reader; - bool isCreate; - }; - - class AsyncTxnAction : public etcdv3::Action - { - public: - AsyncTxnAction(etcdv3::ActionParameters && params, etcdv3::Transaction const &tx); - AsyncTxnResponse ParseResponse(); - private: - TxnResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncUnlockAction : public etcdv3::Action - { - public: - AsyncUnlockAction(etcdv3::ActionParameters && params); - AsyncUnlockResponse ParseResponse(); - private: - UnlockResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncUpdateAction : public etcdv3::Action - { - public: - AsyncUpdateAction(etcdv3::ActionParameters && params); - AsyncTxnResponse ParseResponse(); - private: - TxnResponse reply; - std::unique_ptr> response_reader; - }; - - class AsyncWatchAction : public etcdv3::Action - { - public: - AsyncWatchAction(etcdv3::ActionParameters && params); - AsyncWatchResponse ParseResponse(); - void waitForResponse(); - void waitForResponse(std::function callback); - void CancelWatch(); - bool Cancelled() const; - private: - int64_t watch_id = -1; - WatchResponse reply; - std::unique_ptr> stream; - std::atomic_bool isCancelled; - }; -} +namespace etcdv3 { +class AsyncCampaignAction : public etcdv3::Action { + public: + AsyncCampaignAction(etcdv3::ActionParameters&& params); + AsyncCampaignResponse ParseResponse(); + + private: + CampaignResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncCompareAndDeleteAction : public etcdv3::Action { + public: + AsyncCompareAndDeleteAction(etcdv3::ActionParameters&& params, + etcdv3::AtomicityType type); + AsyncTxnResponse ParseResponse(); + + private: + TxnResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncCompareAndSwapAction : public etcdv3::Action { + public: + AsyncCompareAndSwapAction(etcdv3::ActionParameters&& params, + etcdv3::AtomicityType type); + AsyncTxnResponse ParseResponse(); + + private: + TxnResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncDeleteAction : public etcdv3::Action { + public: + AsyncDeleteAction(etcdv3::ActionParameters&& params); + AsyncDeleteResponse ParseResponse(); + + private: + DeleteRangeResponse reply; + std::unique_ptr> + response_reader; +}; + +class AsyncHeadAction : public etcdv3::Action { + public: + AsyncHeadAction(etcdv3::ActionParameters&& params); + AsyncHeadResponse ParseResponse(); + + private: + RangeResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncLeaderAction : public etcdv3::Action { + public: + AsyncLeaderAction(etcdv3::ActionParameters&& params); + AsyncLeaderResponse ParseResponse(); + + private: + LeaderResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncLeaseGrantAction : public etcdv3::Action { + public: + AsyncLeaseGrantAction(etcdv3::ActionParameters&& params); + AsyncLeaseGrantResponse ParseResponse(); + + private: + LeaseGrantResponse reply; + std::unique_ptr> + response_reader; +}; + +class AsyncLeaseKeepAliveAction : public etcdv3::Action { + public: + AsyncLeaseKeepAliveAction(etcdv3::ActionParameters&& params); + AsyncLeaseKeepAliveResponse ParseResponse(); + + etcd::Response Refresh(); + void CancelKeepAlive(); + bool Cancelled() const; + + private: + etcdv3::ActionParameters& mutable_parameters(); + + LeaseKeepAliveResponse reply; + std::unique_ptr< + ClientAsyncReaderWriter> + stream; + + LeaseKeepAliveRequest req; + bool isCancelled; + std::recursive_mutex protect_is_cancelled; + + friend class etcd::KeepAlive; +}; + +class AsyncLeaseLeasesAction : public etcdv3::Action { + public: + AsyncLeaseLeasesAction(etcdv3::ActionParameters&& params); + AsyncLeaseLeasesResponse ParseResponse(); + + private: + LeaseLeasesResponse reply; + std::unique_ptr> + response_reader; +}; + +class AsyncLeaseRevokeAction : public etcdv3::Action { + public: + AsyncLeaseRevokeAction(etcdv3::ActionParameters&& params); + AsyncLeaseRevokeResponse ParseResponse(); + + private: + LeaseRevokeResponse reply; + std::unique_ptr> + response_reader; +}; + +class AsyncLeaseTimeToLiveAction : public etcdv3::Action { + public: + AsyncLeaseTimeToLiveAction(etcdv3::ActionParameters&& params); + AsyncLeaseTimeToLiveResponse ParseResponse(); + + private: + LeaseTimeToLiveResponse reply; + std::unique_ptr> + response_reader; +}; + +class AsyncLockAction : public etcdv3::Action { + public: + AsyncLockAction(etcdv3::ActionParameters&& params); + AsyncLockResponse ParseResponse(); + + private: + LockResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncObserveAction : public etcdv3::Action { + public: + AsyncObserveAction(etcdv3::ActionParameters&& params); + AsyncObserveResponse ParseResponse(); + void waitForResponse(); + void CancelObserve(); + bool Cancelled() const; + + private: + LeaderResponse reply; + std::unique_ptr> response_reader; + std::atomic_bool isCancelled; + std::mutex protect_is_cancalled; +}; + +class AsyncProclaimAction : public etcdv3::Action { + public: + AsyncProclaimAction(etcdv3::ActionParameters&& params); + AsyncProclaimResponse ParseResponse(); + + private: + ProclaimResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncPutAction : public etcdv3::Action { + public: + AsyncPutAction(etcdv3::ActionParameters&& params); + AsyncPutResponse ParseResponse(); + + private: + PutResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncRangeAction : public etcdv3::Action { + public: + AsyncRangeAction(etcdv3::ActionParameters&& params); + AsyncRangeResponse ParseResponse(); + + private: + RangeResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncResignAction : public etcdv3::Action { + public: + AsyncResignAction(etcdv3::ActionParameters&& params); + AsyncResignResponse ParseResponse(); + + private: + ResignResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncSetAction : public etcdv3::Action { + public: + AsyncSetAction(etcdv3::ActionParameters&& params, bool create = false); + AsyncTxnResponse ParseResponse(); + + private: + TxnResponse reply; + std::unique_ptr> response_reader; + bool isCreate; +}; + +class AsyncTxnAction : public etcdv3::Action { + public: + AsyncTxnAction(etcdv3::ActionParameters&& params, + etcdv3::Transaction const& tx); + AsyncTxnResponse ParseResponse(); + + private: + TxnResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncUnlockAction : public etcdv3::Action { + public: + AsyncUnlockAction(etcdv3::ActionParameters&& params); + AsyncUnlockResponse ParseResponse(); + + private: + UnlockResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncUpdateAction : public etcdv3::Action { + public: + AsyncUpdateAction(etcdv3::ActionParameters&& params); + AsyncTxnResponse ParseResponse(); + + private: + TxnResponse reply; + std::unique_ptr> response_reader; +}; + +class AsyncWatchAction : public etcdv3::Action { + public: + AsyncWatchAction(etcdv3::ActionParameters&& params); + AsyncWatchResponse ParseResponse(); + void waitForResponse(); + void waitForResponse(std::function callback); + void CancelWatch(); + bool Cancelled() const; + + private: + int64_t watch_id = -1; + WatchResponse reply; + std::unique_ptr> stream; + std::atomic_bool isCancelled; +}; +} // namespace etcdv3 #endif diff --git a/etcd/v3/KeyValue.hpp b/etcd/v3/KeyValue.hpp index 010df1e..709abd6 100644 --- a/etcd/v3/KeyValue.hpp +++ b/etcd/v3/KeyValue.hpp @@ -3,18 +3,16 @@ #include "proto/kv.pb.h" +namespace etcdv3 { +class KeyValue { + public: + KeyValue(); + mvccpb::KeyValue kvs; + void set_ttl(int ttl); + int get_ttl() const; -namespace etcdv3 -{ - class KeyValue - { - public: - KeyValue(); - mvccpb::KeyValue kvs; - void set_ttl(int ttl); - int get_ttl() const; - private: - int ttl; - }; -} + private: + int ttl; +}; +} // namespace etcdv3 #endif diff --git a/etcd/v3/Transaction.hpp b/etcd/v3/Transaction.hpp index fba4085..5ad6c29 100644 --- a/etcd/v3/Transaction.hpp +++ b/etcd/v3/Transaction.hpp @@ -1,60 +1,67 @@ #ifndef V3_SRC_TRANSACTION_HPP_ #define V3_SRC_TRANSACTION_HPP_ -#include #include +#include namespace etcdserverpb { - class TxnRequest; +class TxnRequest; } namespace etcdv3 { enum class CompareResult { - EQUAL = 0, - GREATER = 1, - LESS = 2, - NOT_EQUAL = 3, + EQUAL = 0, + GREATER = 1, + LESS = 2, + NOT_EQUAL = 3, }; enum class CompareTarget { - VERSION = 0, - CREATE = 1, - MOD = 2, - VALUE = 3, - LEASE = 4, + VERSION = 0, + CREATE = 1, + MOD = 2, + VALUE = 3, + LEASE = 4, }; class Transaction { -public: - Transaction(); - Transaction(std::string const&); - virtual ~Transaction(); - - // Set a new key for different comparisons and /put/get/delete requests. - void reset_key(std::string const& newkey); - - void init_compare(CompareResult, CompareTarget); - void init_compare(std::string const &old_value, CompareResult, CompareTarget); - void init_compare(int64_t old_value, CompareResult, CompareTarget); - - void setup_basic_failure_operation(std::string const &key); - void setup_set_failure_operation(std::string const &key, std::string const &value, int64_t leaseid); - void setup_basic_create_sequence(std::string const &key, std::string const &value, int64_t leaseid); - void setup_compare_and_swap_sequence(std::string const &valueToSwap, int64_t leaseid); - void setup_delete_sequence(std::string const &key, std::string const &range_end, bool recursive); - void setup_delete_failure_operation(std::string const &key, std::string const &range_end, bool recursive); - void setup_compare_and_delete_operation(std::string const& key); - - // update without `get` and no `prev_kv` returned - void setup_put(std::string const &key, std::string const &value); - void setup_delete(std::string const &key); - - std::shared_ptr txn_request; - private: - std::string key; + public: + Transaction(); + Transaction(std::string const&); + virtual ~Transaction(); + + // Set a new key for different comparisons and /put/get/delete requests. + void reset_key(std::string const& newkey); + + void init_compare(CompareResult, CompareTarget); + void init_compare(std::string const& old_value, CompareResult, CompareTarget); + void init_compare(int64_t old_value, CompareResult, CompareTarget); + + void setup_basic_failure_operation(std::string const& key); + void setup_set_failure_operation(std::string const& key, + std::string const& value, int64_t leaseid); + void setup_basic_create_sequence(std::string const& key, + std::string const& value, int64_t leaseid); + void setup_compare_and_swap_sequence(std::string const& valueToSwap, + int64_t leaseid); + void setup_delete_sequence(std::string const& key, + std::string const& range_end, bool recursive); + void setup_delete_failure_operation(std::string const& key, + std::string const& range_end, + bool recursive); + void setup_compare_and_delete_operation(std::string const& key); + + // update without `get` and no `prev_kv` returned + void setup_put(std::string const& key, std::string const& value); + void setup_delete(std::string const& key); + + std::shared_ptr txn_request; + + private: + std::string key; }; -} +} // namespace etcdv3 #endif diff --git a/etcd/v3/V3Response.hpp b/etcd/v3/V3Response.hpp index 2fa6eb0..c5042b7 100644 --- a/etcd/v3/V3Response.hpp +++ b/etcd/v3/V3Response.hpp @@ -7,59 +7,58 @@ #include "etcd/v3/KeyValue.hpp" -namespace etcdv3 -{ - class V3Response - { - public: - V3Response(): error_code(0), index(0){}; - void set_error_code(int code); - int get_error_code() const; - std::string const & get_error_message() const; - void set_error_message(std::string msg); - void set_action(std::string action); - int64_t get_index() const; - std::string const & get_action() const; - std::vector const & get_values() const; - std::vector const & get_prev_values() const; - etcdv3::KeyValue const & get_value() const; - etcdv3::KeyValue const & get_prev_value() const; - bool has_values() const; - int64_t get_compact_revision() const; - void set_compact_revision(const int64_t compact_revision); - int64_t get_watch_id() const; - void set_watch_id(const int64_t watch_id); - void set_lock_key(std::string const &key); - std::string const &get_lock_key() const; - void set_name(std::string const &name); - std::string const &get_name() const; - std::vector const & get_events() const; - uint64_t get_cluster_id() const; - uint64_t get_member_id() const; - uint64_t get_raft_term() const; - std::vector const &get_leases() const; - protected: - int error_code; - int64_t index; - std::string error_message; - std::string action; - etcdv3::KeyValue value; - etcdv3::KeyValue prev_value; - std::vector values; - std::vector prev_values; - int64_t compact_revision = -1; - int64_t watch_id = -1; - std::string lock_key; // for lock - std::string name; // for campaign (in v3election) - std::vector events; // for watch +namespace etcdv3 { +class V3Response { + public: + V3Response() : error_code(0), index(0){}; + void set_error_code(int code); + int get_error_code() const; + std::string const& get_error_message() const; + void set_error_message(std::string msg); + void set_action(std::string action); + int64_t get_index() const; + std::string const& get_action() const; + std::vector const& get_values() const; + std::vector const& get_prev_values() const; + etcdv3::KeyValue const& get_value() const; + etcdv3::KeyValue const& get_prev_value() const; + bool has_values() const; + int64_t get_compact_revision() const; + void set_compact_revision(const int64_t compact_revision); + int64_t get_watch_id() const; + void set_watch_id(const int64_t watch_id); + void set_lock_key(std::string const& key); + std::string const& get_lock_key() const; + void set_name(std::string const& name); + std::string const& get_name() const; + std::vector const& get_events() const; + uint64_t get_cluster_id() const; + uint64_t get_member_id() const; + uint64_t get_raft_term() const; + std::vector const& get_leases() const; - // cluster metadata - uint64_t cluster_id; - uint64_t member_id; - uint64_t raft_term; + protected: + int error_code; + int64_t index; + std::string error_message; + std::string action; + etcdv3::KeyValue value; + etcdv3::KeyValue prev_value; + std::vector values; + std::vector prev_values; + int64_t compact_revision = -1; + int64_t watch_id = -1; + std::string lock_key; // for lock + std::string name; // for campaign (in v3election) + std::vector events; // for watch - // for lease list - std::vector leases; - }; -} + // cluster metadata + uint64_t cluster_id; + uint64_t member_id; + uint64_t raft_term; + + // for lease list + std::vector leases; +}; +} // namespace etcdv3 #endif diff --git a/etcd/v3/action_constants.hpp b/etcd/v3/action_constants.hpp index a8bf82c..e39132e 100644 --- a/etcd/v3/action_constants.hpp +++ b/etcd/v3/action_constants.hpp @@ -3,72 +3,71 @@ #include -namespace etcdv3 -{ - extern char const * CREATE_ACTION; - extern char const * UPDATE_ACTION; - extern char const * SET_ACTION; - extern char const * GET_ACTION; - extern char const * PUT_ACTION; - extern char const * DELETE_ACTION; - extern char const * COMPARESWAP_ACTION; - extern char const * COMPAREDELETE_ACTION; - extern char const * LOCK_ACTION; - extern char const * UNLOCK_ACTION; - extern char const * TXN_ACTION; - extern char const * WATCH_ACTION; +namespace etcdv3 { +extern char const* CREATE_ACTION; +extern char const* UPDATE_ACTION; +extern char const* SET_ACTION; +extern char const* GET_ACTION; +extern char const* PUT_ACTION; +extern char const* DELETE_ACTION; +extern char const* COMPARESWAP_ACTION; +extern char const* COMPAREDELETE_ACTION; +extern char const* LOCK_ACTION; +extern char const* UNLOCK_ACTION; +extern char const* TXN_ACTION; +extern char const* WATCH_ACTION; - extern char const * LEASEGRANT; - extern char const * LEASEREVOKE; - extern char const * LEASEKEEPALIVE; - extern char const * LEASETIMETOLIVE; - extern char const * LEASELEASES; +extern char const* LEASEGRANT; +extern char const* LEASEREVOKE; +extern char const* LEASEKEEPALIVE; +extern char const* LEASETIMETOLIVE; +extern char const* LEASELEASES; - extern char const * CAMPAIGN_ACTION; - extern char const * PROCLAIM_ACTION; - extern char const * LEADER_ACTION; - extern char const * OBSERVE_ACTION; - extern char const * RESIGN_ACTION; +extern char const* CAMPAIGN_ACTION; +extern char const* PROCLAIM_ACTION; +extern char const* LEADER_ACTION; +extern char const* OBSERVE_ACTION; +extern char const* RESIGN_ACTION; - extern std::string const NUL; +extern std::string const NUL; - extern char const * KEEPALIVE_CREATE; - extern char const * KEEPALIVE_WRITE; - extern char const * KEEPALIVE_READ; - extern char const * KEEPALIVE_DONE; - extern char const * KEEPALIVE_FINISH; +extern char const* KEEPALIVE_CREATE; +extern char const* KEEPALIVE_WRITE; +extern char const* KEEPALIVE_READ; +extern char const* KEEPALIVE_DONE; +extern char const* KEEPALIVE_FINISH; - extern char const * WATCH_CREATE; - extern char const * WATCH_WRITE; - extern char const * WATCH_WRITE_CANCEL; - extern char const * WATCH_WRITES_DONE; - extern char const * WATCH_FINISH; +extern char const* WATCH_CREATE; +extern char const* WATCH_WRITE; +extern char const* WATCH_WRITE_CANCEL; +extern char const* WATCH_WRITES_DONE; +extern char const* WATCH_FINISH; - extern char const * ELECTION_OBSERVE_CREATE; - extern char const * ELECTION_OBSERVE_FINISH; +extern char const* ELECTION_OBSERVE_CREATE; +extern char const* ELECTION_OBSERVE_FINISH; - extern const int ERROR_GRPC_OK; - extern const int ERROR_GRPC_CANCELLED; - extern const int ERROR_GRPC_UNKNOWN; - extern const int ERROR_GRPC_INVALID_ARGUMENT; - extern const int ERROR_GRPC_DEADLINE_EXCEEDED; - extern const int ERROR_GRPC_NOT_FOUND; - extern const int ERROR_GRPC_ALREADY_EXISTS; - extern const int ERROR_GRPC_PERMISSION_DENIED; - extern const int ERROR_GRPC_UNAUTHENTICATED; - extern const int ERROR_GRPC_RESOURCE_EXHAUSTED; - extern const int ERROR_GRPC_FAILED_PRECONDITION; - extern const int ERROR_GRPC_ABORTED; - extern const int ERROR_GRPC_OUT_OF_RANGE; - extern const int ERROR_GRPC_UNIMPLEMENTED; - extern const int ERROR_GRPC_INTERNAL; - extern const int ERROR_GRPC_UNAVAILABLE; - extern const int ERROR_GRPC_DATA_LOSS; +extern const int ERROR_GRPC_OK; +extern const int ERROR_GRPC_CANCELLED; +extern const int ERROR_GRPC_UNKNOWN; +extern const int ERROR_GRPC_INVALID_ARGUMENT; +extern const int ERROR_GRPC_DEADLINE_EXCEEDED; +extern const int ERROR_GRPC_NOT_FOUND; +extern const int ERROR_GRPC_ALREADY_EXISTS; +extern const int ERROR_GRPC_PERMISSION_DENIED; +extern const int ERROR_GRPC_UNAUTHENTICATED; +extern const int ERROR_GRPC_RESOURCE_EXHAUSTED; +extern const int ERROR_GRPC_FAILED_PRECONDITION; +extern const int ERROR_GRPC_ABORTED; +extern const int ERROR_GRPC_OUT_OF_RANGE; +extern const int ERROR_GRPC_UNIMPLEMENTED; +extern const int ERROR_GRPC_INTERNAL; +extern const int ERROR_GRPC_UNAVAILABLE; +extern const int ERROR_GRPC_DATA_LOSS; - extern const int ERROR_KEY_NOT_FOUND; - extern const int ERROR_COMPARE_FAILED; - extern const int ERROR_KEY_ALREADY_EXISTS; - extern const int ERROR_ACTION_CANCELLED; -} +extern const int ERROR_KEY_NOT_FOUND; +extern const int ERROR_COMPARE_FAILED; +extern const int ERROR_KEY_ALREADY_EXISTS; +extern const int ERROR_ACTION_CANCELLED; +} // namespace etcdv3 #endif diff --git a/src/Client.cpp b/src/Client.cpp index f7dd9d1..aac023a 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1,5 +1,6 @@ #if defined(_WIN32) -// see also: https://stackoverflow.com/questions/2561368/illegal-token-on-right-side-of +// see also: +// https://stackoverflow.com/questions/2561368/illegal-token-on-right-side-of #define NOMINMAX #endif @@ -19,8 +20,8 @@ #endif #include -#include #include +#include #include #include #include @@ -31,126 +32,117 @@ #include #include #include "proto/rpc.grpc.pb.h" -#include "proto/v3lock.grpc.pb.h" #include "proto/v3election.grpc.pb.h" +#include "proto/v3lock.grpc.pb.h" #include "etcd/Client.hpp" #include "etcd/KeepAlive.hpp" #include "etcd/Watcher.hpp" -#include "etcd/v3/action_constants.hpp" #include "etcd/v3/Action.hpp" #include "etcd/v3/AsyncGRPC.hpp" #include "etcd/v3/Transaction.hpp" +#include "etcd/v3/action_constants.hpp" -etcd::Client::Client(etcd::SyncClient *client): client(client) -{ +etcd::Client::Client(etcd::SyncClient* client) : client(client) { this->own_client = false; } -etcd::Client* WithClient(etcd::SyncClient *client) -{ +etcd::Client* WithClient(etcd::SyncClient* client) { return new etcd::Client(client); } -etcd::Client::Client(std::string const & address, - std::string const & load_balancer) -{ +etcd::Client::Client(std::string const& address, + std::string const& load_balancer) { this->own_client = true; this->client = new SyncClient(address, load_balancer); } -etcd::Client::Client(std::string const & address, - grpc::ChannelArguments const & arguments) -{ +etcd::Client::Client(std::string const& address, + grpc::ChannelArguments const& arguments) { this->own_client = true; this->client = new SyncClient(address, arguments); } -etcd::Client *etcd::Client::WithUrl(std::string const & etcd_url, - std::string const & load_balancer) { +etcd::Client* etcd::Client::WithUrl(std::string const& etcd_url, + std::string const& load_balancer) { return new etcd::Client(etcd_url, load_balancer); } -etcd::Client *etcd::Client::WithUrl(std::string const & etcd_url, - grpc::ChannelArguments const & arguments) { +etcd::Client* etcd::Client::WithUrl(std::string const& etcd_url, + grpc::ChannelArguments const& arguments) { return new etcd::Client(etcd_url, arguments); } -etcd::Client::Client(std::string const & address, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - std::string const & load_balancer) -{ +etcd::Client::Client(std::string const& address, std::string const& username, + std::string const& password, int const auth_token_ttl, + std::string const& load_balancer) { this->own_client = true; - this->client = new SyncClient(address, username, password, auth_token_ttl, load_balancer); + this->client = new SyncClient(address, username, password, auth_token_ttl, + load_balancer); } -etcd::Client::Client(std::string const & address, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - grpc::ChannelArguments const & arguments) -{ +etcd::Client::Client(std::string const& address, std::string const& username, + std::string const& password, int const auth_token_ttl, + grpc::ChannelArguments const& arguments) { this->own_client = true; - this->client = new SyncClient(address, username, password, auth_token_ttl, arguments); + this->client = + new SyncClient(address, username, password, auth_token_ttl, arguments); } -etcd::Client *etcd::Client::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, +etcd::Client* etcd::Client::WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, int const auth_token_ttl, - std::string const & load_balancer) { - return new etcd::Client(etcd_url, username, password, auth_token_ttl, load_balancer); + std::string const& load_balancer) { + return new etcd::Client(etcd_url, username, password, auth_token_ttl, + load_balancer); } -etcd::Client *etcd::Client::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, +etcd::Client* etcd::Client::WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, int const auth_token_ttl, - grpc::ChannelArguments const & arguments) { - return new etcd::Client(etcd_url, username, password, auth_token_ttl, arguments); + grpc::ChannelArguments const& arguments) { + return new etcd::Client(etcd_url, username, password, auth_token_ttl, + arguments); } - -etcd::Client::Client(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer) -{ +etcd::Client::Client(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, + std::string const& load_balancer) { this->own_client = true; - this->client = new SyncClient(address, ca, cert, privkey, target_name_override, load_balancer); + this->client = new SyncClient(address, ca, cert, privkey, + target_name_override, load_balancer); } -etcd::Client::Client(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - grpc::ChannelArguments const & arguments) -{ +etcd::Client::Client(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& target_name_override, + grpc::ChannelArguments const& arguments) { this->own_client = true; - this->client = new SyncClient(address, ca, cert, privkey, target_name_override, arguments); + this->client = new SyncClient(address, ca, cert, privkey, + target_name_override, arguments); } -etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer) { - return new etcd::Client(etcd_url, ca, cert, privkey, target_name_override, load_balancer); +etcd::Client* etcd::Client::WithSSL(std::string const& etcd_url, + std::string const& ca, + std::string const& cert, + std::string const& privkey, + std::string const& target_name_override, + std::string const& load_balancer) { + return new etcd::Client(etcd_url, ca, cert, privkey, target_name_override, + load_balancer); } -etcd::Client *etcd::Client::WithSSL(std::string const & etcd_url, - grpc::ChannelArguments const & arguments, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override) { - return new etcd::Client(etcd_url, ca, cert, privkey, target_name_override, arguments); +etcd::Client* etcd::Client::WithSSL(std::string const& etcd_url, + grpc::ChannelArguments const& arguments, + std::string const& ca, + std::string const& cert, + std::string const& privkey, + std::string const& target_name_override) { + return new etcd::Client(etcd_url, ca, cert, privkey, target_name_override, + arguments); } etcd::Client::~Client() { @@ -159,7 +151,6 @@ etcd::Client::~Client() { } } - namespace etcd { namespace detail { @@ -168,37 +159,46 @@ namespace detail { // Inspired by: https://stackoverflow.com/a/20669290/5080177 template -class capture_impl -{ - mutable A a; - mutable F f; -public: - capture_impl(A && a, F && f) - : a{std::forward(a)}, f{std::forward(f)} - {} - - template auto operator()( Ts&&...args ) - -> decltype(std::forward(f)(std::forward(a), std::forward(args)... )) - { - return std::forward(f)(std::forward(a), std::forward(args)... ); - } - - template auto operator()( Ts&&...args ) const - -> decltype(std::forward(f)(std::forward(a), std::forward(args)... )) - { - return std::forward(f)(std::forward(a), std::forward(args)... ); - } +class capture_impl { + mutable A a; + mutable F f; + + public: + capture_impl(A&& a, F&& f) : a{std::forward(a)}, f{std::forward(f)} {} + + template + auto operator()(Ts&&... args) + -> decltype(std::forward(f)(std::forward(a), + std::forward(args)...)) { + return std::forward(f)(std::forward(a), std::forward(args)...); + } + + template + auto operator()(Ts&&... args) const + -> decltype(std::forward(f)(std::forward(a), + std::forward(args)...)) { + return std::forward(f)(std::forward(a), std::forward(args)...); + } }; template -static capture_impl capture(A && a, F && f) -{ - return capture_impl(std::forward(a), std::forward(f)); +static capture_impl capture(A&& a, F&& f) { + return capture_impl(std::forward(a), std::forward(f)); } template -static auto asyncify(F && fn, Params && params, Ts... args) -> pplx::task(params), std::bind(std::forward(fn), std::placeholders::_1, std::forward(args)...))())> { - return pplx::task(params), std::bind(std::forward(fn), std::placeholders::_1, std::forward(args)...))())>(capture(std::forward(params), std::bind(std::forward(fn), std::placeholders::_1, std::forward(args)...))); +static auto asyncify(F&& fn, Params&& params, Ts... args) + -> pplx::task(params), + std::bind(std::forward(fn), + std::placeholders::_1, + std::forward(args)...))())> { + return pplx::task(params), + std::bind(std::forward(fn), std::placeholders::_1, + std::forward(args)...))())>( + capture(std::forward(params), + std::bind(std::forward(fn), std::placeholders::_1, + std::forward(args)...))); } } // namespace detail @@ -208,388 +208,434 @@ using responser_t = etcd::Response (*)(std::shared_ptr); } // namespace etcd -pplx::task etcd::Client::head() -{ +pplx::task etcd::Client::head() { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->head_internal()); + static_cast>(Response::create), + this->client->head_internal()); } -pplx::task etcd::Client::get(std::string const & key) -{ +pplx::task etcd::Client::get(std::string const& key) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->get_internal(key)); + static_cast>( + Response::create), + this->client->get_internal(key)); } -pplx::task etcd::Client::get(std::string const & key, int64_t revision) -{ +pplx::task etcd::Client::get(std::string const& key, + int64_t revision) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->get_internal(key, revision)); + static_cast>( + Response::create), + this->client->get_internal(key, revision)); } -pplx::task etcd::Client::set(std::string const & key, std::string const & value, int ttl) -{ +pplx::task etcd::Client::set(std::string const& key, + std::string const& value, + int ttl) { if (ttl > 0) { - return this->leasegrant(ttl).then([this, key, value](pplx::task const &task) { - auto resp = task.get(); - if (resp.error_code() == 0) { - return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->set_internal(key, value, resp.value().lease())); - } else { - return pplx::task_from_result(resp); - } - }); + return this->leasegrant(ttl).then( + [this, key, value](pplx::task const& task) { + auto resp = task.get(); + if (resp.error_code() == 0) { + return etcd::detail::asyncify( + static_cast>( + Response::create), + this->client->set_internal(key, value, resp.value().lease())); + } else { + return pplx::task_from_result(resp); + } + }); } else { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->set_internal(key, value, 0)); + static_cast>(Response::create), + this->client->set_internal(key, value, 0)); } } -pplx::task etcd::Client::set(std::string const & key, std::string const & value, int64_t leaseid) -{ +pplx::task etcd::Client::set(std::string const& key, + std::string const& value, + int64_t leaseid) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->set_internal(key, value, leaseid)); } -pplx::task etcd::Client::add(std::string const & key, std::string const & value, int ttl) -{ +pplx::task etcd::Client::add(std::string const& key, + std::string const& value, + int ttl) { if (ttl > 0) { - return this->leasegrant(ttl).then([this, key, value](pplx::task const &task) { - auto resp = task.get(); - if (resp.error_code() == 0) { - return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->add_internal(key, value, resp.value().lease())); - } else { - return pplx::task_from_result(resp); - } - }); + return this->leasegrant(ttl).then( + [this, key, value](pplx::task const& task) { + auto resp = task.get(); + if (resp.error_code() == 0) { + return etcd::detail::asyncify( + static_cast>( + Response::create), + this->client->add_internal(key, value, resp.value().lease())); + } else { + return pplx::task_from_result(resp); + } + }); } else { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->add_internal(key, value, 0)); + static_cast>(Response::create), + this->client->add_internal(key, value, 0)); } } -pplx::task etcd::Client::add(std::string const & key, std::string const & value, int64_t leaseid) -{ +pplx::task etcd::Client::add(std::string const& key, + std::string const& value, + int64_t leaseid) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->add_internal(key, value, leaseid)); } -pplx::task etcd::Client::put(std::string const & key, std::string const & value) { +pplx::task etcd::Client::put(std::string const& key, + std::string const& value) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->put_internal(key, value)); } -pplx::task etcd::Client::modify(std::string const & key, std::string const & value, int ttl) -{ +pplx::task etcd::Client::modify(std::string const& key, + std::string const& value, + int ttl) { if (ttl > 0) { - return this->leasegrant(ttl).then([this, key, value](pplx::task const &task) { - auto resp = task.get(); - if (resp.error_code() == 0) { - return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_internal(key, value, resp.value().lease())); - } else { - return pplx::task_from_result(resp); - } - }); + return this->leasegrant(ttl).then( + [this, key, value](pplx::task const& task) { + auto resp = task.get(); + if (resp.error_code() == 0) { + return etcd::detail::asyncify( + static_cast>( + Response::create), + this->client->modify_internal(key, value, + resp.value().lease())); + } else { + return pplx::task_from_result(resp); + } + }); } else { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_internal(key, value, 0)); + static_cast>(Response::create), + this->client->modify_internal(key, value, 0)); } } -pplx::task etcd::Client::modify(std::string const & key, std::string const & value, int64_t leaseid) -{ +pplx::task etcd::Client::modify(std::string const& key, + std::string const& value, + int64_t leaseid) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->modify_internal(key, value, leaseid)); } -pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int ttl) -{ +pplx::task etcd::Client::modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, + int ttl) { if (ttl > 0) { - return this->leasegrant(ttl).then([this, key, value, old_value](pplx::task const &task) { - auto resp = task.get(); - if (resp.error_code() == 0) { - return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, 0, old_value, resp.value().lease(), etcdv3::AtomicityType::PREV_VALUE)); - } else { - return pplx::task_from_result(resp); - } - }); + return this->leasegrant(ttl).then( + [this, key, value, old_value](pplx::task const& task) { + auto resp = task.get(); + if (resp.error_code() == 0) { + return etcd::detail::asyncify( + static_cast>( + Response::create), + this->client->modify_if_internal( + key, value, 0, old_value, resp.value().lease(), + etcdv3::AtomicityType::PREV_VALUE)); + } else { + return pplx::task_from_result(resp); + } + }); } else { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, 0, old_value, 0, etcdv3::AtomicityType::PREV_VALUE)); + static_cast>( + Response::create), + this->client->modify_if_internal(key, value, 0, old_value, 0, + etcdv3::AtomicityType::PREV_VALUE)); } } -pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int64_t leaseid) -{ +pplx::task etcd::Client::modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, + int64_t leaseid) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, 0, old_value, leaseid, etcdv3::AtomicityType::PREV_VALUE)); + static_cast>( + Response::create), + this->client->modify_if_internal(key, value, 0, old_value, leaseid, + etcdv3::AtomicityType::PREV_VALUE)); } -pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, int64_t old_index, int ttl) -{ +pplx::task etcd::Client::modify_if(std::string const& key, + std::string const& value, + int64_t old_index, int ttl) { if (ttl > 0) { - return this->leasegrant(ttl).then([this, key, value, old_index](pplx::task const &task) { - auto resp = task.get(); - if (resp.error_code() == 0) { - return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, old_index, "", resp.value().lease(), etcdv3::AtomicityType::PREV_INDEX)); - } else { - return pplx::task_from_result(resp); - } - }); + return this->leasegrant(ttl).then( + [this, key, value, old_index](pplx::task const& task) { + auto resp = task.get(); + if (resp.error_code() == 0) { + return etcd::detail::asyncify( + static_cast>( + Response::create), + this->client->modify_if_internal( + key, value, old_index, "", resp.value().lease(), + etcdv3::AtomicityType::PREV_INDEX)); + } else { + return pplx::task_from_result(resp); + } + }); } else { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, old_index, "", 0, etcdv3::AtomicityType::PREV_INDEX)); + static_cast>( + Response::create), + this->client->modify_if_internal(key, value, old_index, "", 0, + etcdv3::AtomicityType::PREV_INDEX)); } } -pplx::task etcd::Client::modify_if(std::string const & key, std::string const & value, int64_t old_index, int64_t leaseid) -{ +pplx::task etcd::Client::modify_if(std::string const& key, + std::string const& value, + int64_t old_index, + int64_t leaseid) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->modify_if_internal(key, value, old_index, "", leaseid, etcdv3::AtomicityType::PREV_INDEX)); + static_cast>( + Response::create), + this->client->modify_if_internal(key, value, old_index, "", leaseid, + etcdv3::AtomicityType::PREV_INDEX)); } -pplx::task etcd::Client::rm(std::string const & key) -{ +pplx::task etcd::Client::rm(std::string const& key) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->rm_internal(key)); } -pplx::task etcd::Client::rm_if(std::string const & key, std::string const & old_value) -{ +pplx::task etcd::Client::rm_if(std::string const& key, + std::string const& old_value) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->rm_if_internal(key, 0, old_value, etcdv3::AtomicityType::PREV_VALUE)); + static_cast>( + Response::create), + this->client->rm_if_internal(key, 0, old_value, + etcdv3::AtomicityType::PREV_VALUE)); } -pplx::task etcd::Client::rm_if(std::string const & key, int64_t old_index) -{ +pplx::task etcd::Client::rm_if(std::string const& key, + int64_t old_index) { return etcd::detail::asyncify( - static_cast>(Response::create), - this->client->rm_if_internal(key, old_index, "", etcdv3::AtomicityType::PREV_INDEX)); + static_cast>( + Response::create), + this->client->rm_if_internal(key, old_index, "", + etcdv3::AtomicityType::PREV_INDEX)); } -pplx::task etcd::Client::rmdir(std::string const & key, bool recursive) -{ +pplx::task etcd::Client::rmdir(std::string const& key, + bool recursive) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->rmdir_internal(key, recursive)); } -pplx::task etcd::Client::rmdir(std::string const & key, const char *range_end) -{ +pplx::task etcd::Client::rmdir(std::string const& key, + const char* range_end) { return this->rmdir(key, std::string(range_end)); } -pplx::task etcd::Client::rmdir(std::string const & key, std::string const &range_end) -{ +pplx::task etcd::Client::rmdir(std::string const& key, + std::string const& range_end) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->rmdir_internal(key, range_end)); } -pplx::task etcd::Client::ls(std::string const & key) -{ +pplx::task etcd::Client::ls(std::string const& key) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, 0)); } -pplx::task etcd::Client::ls(std::string const & key, size_t const limit) -{ +pplx::task etcd::Client::ls(std::string const& key, + size_t const limit) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, limit)); } -pplx::task etcd::Client::ls(std::string const & key, size_t const limit, int64_t revision) -{ +pplx::task etcd::Client::ls(std::string const& key, + size_t const limit, + int64_t revision) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, limit, false, revision)); } -pplx::task etcd::Client::ls(std::string const & key, std::string const &range_end) -{ +pplx::task etcd::Client::ls(std::string const& key, + std::string const& range_end) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, 0)); } -pplx::task etcd::Client::ls(std::string const & key, std::string const &range_end, size_t const limit) -{ +pplx::task etcd::Client::ls(std::string const& key, + std::string const& range_end, + size_t const limit) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, limit)); } -pplx::task etcd::Client::ls(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision) -{ +pplx::task etcd::Client::ls(std::string const& key, + std::string const& range_end, + size_t const limit, + int64_t revision) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, limit, false, revision)); } -pplx::task etcd::Client::keys(std::string const & key) -{ +pplx::task etcd::Client::keys(std::string const& key) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, 0, true)); } -pplx::task etcd::Client::keys(std::string const & key, size_t const limit) -{ +pplx::task etcd::Client::keys(std::string const& key, + size_t const limit) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, limit, true)); } -pplx::task etcd::Client::keys(std::string const & key, size_t const limit, int64_t revision) -{ +pplx::task etcd::Client::keys(std::string const& key, + size_t const limit, + int64_t revision) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, limit, true, revision)); } -pplx::task etcd::Client::keys(std::string const & key, std::string const &range_end) -{ +pplx::task etcd::Client::keys(std::string const& key, + std::string const& range_end) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, 0, true)); } -pplx::task etcd::Client::keys(std::string const & key, std::string const &range_end, size_t const limit) -{ +pplx::task etcd::Client::keys(std::string const& key, + std::string const& range_end, + size_t const limit) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, limit, true)); } -pplx::task etcd::Client::keys(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision) -{ +pplx::task etcd::Client::keys(std::string const& key, + std::string const& range_end, + size_t const limit, + int64_t revision) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->ls_internal(key, range_end, limit, true, revision)); } -pplx::task etcd::Client::watch(std::string const & key, bool recursive) -{ +pplx::task etcd::Client::watch(std::string const& key, + bool recursive) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->watch_internal(key, 0, recursive)); } -pplx::task etcd::Client::watch(std::string const & key, int64_t fromIndex, bool recursive) -{ +pplx::task etcd::Client::watch(std::string const& key, + int64_t fromIndex, + bool recursive) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->watch_internal(key, fromIndex, recursive)); } -pplx::task etcd::Client::watch(std::string const & key, const char *range_end) -{ +pplx::task etcd::Client::watch(std::string const& key, + const char* range_end) { return this->watch(key, std::string(range_end)); } -pplx::task etcd::Client::watch(std::string const & key, std::string const & range_end) -{ +pplx::task etcd::Client::watch(std::string const& key, + std::string const& range_end) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->watch_internal(key, range_end, 0)); } -pplx::task etcd::Client::watch(std::string const & key, std::string const & range_end, int64_t fromIndex) -{ +pplx::task etcd::Client::watch(std::string const& key, + std::string const& range_end, + int64_t fromIndex) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->watch_internal(key, range_end, fromIndex)); } -pplx::task etcd::Client::leasegrant(int ttl) -{ +pplx::task etcd::Client::leasegrant(int ttl) { // See Note [lease with TTL and issue the actual request] - return pplx::task([this, ttl]() { - return this->client->leasegrant(ttl); - }); + return pplx::task( + [this, ttl]() { return this->client->leasegrant(ttl); }); } -pplx::task> etcd::Client::leasekeepalive(int ttl) { +pplx::task> etcd::Client::leasekeepalive( + int ttl) { // See Note [lease with TTL and issue the actual request] - return pplx::task>([this, ttl]() { - return this->client->leasekeepalive(ttl); - }); + return pplx::task>( + [this, ttl]() { return this->client->leasekeepalive(ttl); }); } -pplx::task etcd::Client::leaserevoke(int64_t lease_id) -{ +pplx::task etcd::Client::leaserevoke(int64_t lease_id) { return etcd::detail::asyncify( - static_cast>(Response::create), + static_cast>( + Response::create), this->client->leaserevoke_internal(lease_id)); } -pplx::task etcd::Client::leasetimetolive(int64_t lease_id) -{ +pplx::task etcd::Client::leasetimetolive(int64_t lease_id) { return etcd::detail::asyncify( - static_cast>(Response::create), + static_cast>( + Response::create), this->client->leasetimetolive_internal(lease_id)); } -pplx::task etcd::Client::leases() -{ +pplx::task etcd::Client::leases() { return etcd::detail::asyncify( - static_cast>(Response::create), + static_cast>( + Response::create), this->client->leases_internal()); } -pplx::task etcd::Client::lock(std::string const &key) { - static const int DEFAULT_LEASE_TTL_FOR_LOCK = 10; // see also etcd::SyncClient::lock +pplx::task etcd::Client::lock(std::string const& key) { + static const int DEFAULT_LEASE_TTL_FOR_LOCK = + 10; // see also etcd::SyncClient::lock return this->lock(key, DEFAULT_LEASE_TTL_FOR_LOCK); } -pplx::task etcd::Client::lock(std::string const &key, +pplx::task etcd::Client::lock(std::string const& key, const bool sync) { - static const int DEFAULT_LEASE_TTL_FOR_LOCK = 10; // see also etcd::SyncClient::lock + static const int DEFAULT_LEASE_TTL_FOR_LOCK = + 10; // see also etcd::SyncClient::lock return this->lock(key, DEFAULT_LEASE_TTL_FOR_LOCK, sync); } -pplx::task etcd::Client::lock(std::string const &key, +pplx::task etcd::Client::lock(std::string const& key, int lease_ttl) { // See Note [lease with TTL and issue the actual request] // See also SyncClient::lock // // We don't separate the keepalive step and lock step to avoid leaving many - // busy-waiting keepalive tasks when waiting for the locks due to the contention - // of async threadpool. - return pplx::task([this, key, lease_ttl]() { - return this->client->lock(key, lease_ttl); - }); + // busy-waiting keepalive tasks when waiting for the locks due to the + // contention of async threadpool. + return pplx::task( + [this, key, lease_ttl]() { return this->client->lock(key, lease_ttl); }); } -pplx::task etcd::Client::lock(std::string const &key, - int lease_ttl, - const bool sync) { +pplx::task etcd::Client::lock(std::string const& key, + int lease_ttl, const bool sync) { if (sync) { pplx::task_completion_event event; event.set(this->client->lock(key, lease_ttl)); @@ -599,14 +645,14 @@ pplx::task etcd::Client::lock(std::string const &key, } } -pplx::task etcd::Client::lock_with_lease(std::string const &key, +pplx::task etcd::Client::lock_with_lease(std::string const& key, int64_t lease_id) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->lock_with_lease_internal(key, lease_id)); } -pplx::task etcd::Client::lock_with_lease(std::string const &key, +pplx::task etcd::Client::lock_with_lease(std::string const& key, int64_t lease_id, const bool sync) { if (sync) { @@ -618,51 +664,57 @@ pplx::task etcd::Client::lock_with_lease(std::string const &key, } } -pplx::task etcd::Client::unlock(std::string const &lock_key) { +pplx::task etcd::Client::unlock(std::string const& lock_key) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->unlock_internal(lock_key)); } -pplx::task etcd::Client::txn(etcdv3::Transaction const &txn) { +pplx::task etcd::Client::txn(etcdv3::Transaction const& txn) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->txn_internal(txn)); } -pplx::task etcd::Client::campaign( - std::string const &name, int64_t lease_id, std::string const &value) { +pplx::task etcd::Client::campaign(std::string const& name, + int64_t lease_id, + std::string const& value) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->campaign_internal(name, lease_id, value)); } -pplx::task etcd::Client::proclaim( - std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value) { +pplx::task etcd::Client::proclaim(std::string const& name, + int64_t lease_id, + std::string const& key, + int64_t revision, + std::string const& value) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->proclaim_internal(name, lease_id, key, revision, value)); } -pplx::task etcd::Client::leader(std::string const &name) { +pplx::task etcd::Client::leader(std::string const& name) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->leader_internal(name)); } -std::unique_ptr etcd::Client::observe(std::string const &name) { +std::unique_ptr etcd::Client::observe( + std::string const& name) { return this->client->observe(name); } -pplx::task etcd::Client::resign( - std::string const &name, int64_t lease_id, std::string const &key, int64_t revision) { +pplx::task etcd::Client::resign(std::string const& name, + int64_t lease_id, + std::string const& key, + int64_t revision) { return etcd::detail::asyncify( static_cast>(Response::create), this->client->resign_internal(name, lease_id, key, revision)); } -const std::string &etcd::Client::current_auth_token() const { +const std::string& etcd::Client::current_auth_token() const { return this->client->current_auth_token(); } @@ -670,72 +722,61 @@ std::shared_ptr etcd::Client::grpc_channel() const { return this->client->grpc_channel(); } -etcd::SyncClient* etcd::Client::sync_client() const { - return this->client; -} +etcd::SyncClient* etcd::Client::sync_client() const { return this->client; } // watchers from the async client -etcd::Watcher::Watcher(Client const &client, std::string const & key, +etcd::Watcher::Watcher(Client const& client, std::string const& key, std::function callback, - std::function wait_callback, - bool recursive): - Watcher(*client.sync_client(), key, callback, wait_callback, recursive) { -} + std::function wait_callback, bool recursive) + : Watcher(*client.sync_client(), key, callback, wait_callback, recursive) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, - std::string const &range_end, +etcd::Watcher::Watcher(Client const& client, std::string const& key, + std::string const& range_end, std::function callback, - std::function wait_callback): - Watcher(*client.sync_client(), key, range_end, callback, wait_callback) { -} + std::function wait_callback) + : Watcher(*client.sync_client(), key, range_end, callback, wait_callback) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, int64_t fromIndex, +etcd::Watcher::Watcher(Client const& client, std::string const& key, + int64_t fromIndex, std::function callback, - std::function wait_callback, - bool recursive): - Watcher(*client.sync_client(), key, fromIndex, callback, wait_callback, recursive) { -} + std::function wait_callback, bool recursive) + : Watcher(*client.sync_client(), key, fromIndex, callback, wait_callback, + recursive) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, +etcd::Watcher::Watcher(Client const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, std::function callback, - std::function wait_callback): - Watcher(*client.sync_client(), key, range_end, fromIndex, callback, wait_callback) { -} + std::function wait_callback) + : Watcher(*client.sync_client(), key, range_end, fromIndex, callback, + wait_callback) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, - std::function callback, - bool recursive): - Watcher(*client.sync_client(), key, callback, recursive) { -} +etcd::Watcher::Watcher(Client const& client, std::string const& key, + std::function callback, bool recursive) + : Watcher(*client.sync_client(), key, callback, recursive) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, - std::string const &range_end, - std::function callback): - Watcher(*client.sync_client(), key, range_end, callback) { -} +etcd::Watcher::Watcher(Client const& client, std::string const& key, + std::string const& range_end, + std::function callback) + : Watcher(*client.sync_client(), key, range_end, callback) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive): - Watcher(*client.sync_client(), key, fromIndex, callback, recursive) { -} +etcd::Watcher::Watcher(Client const& client, std::string const& key, + int64_t fromIndex, + std::function callback, bool recursive) + : Watcher(*client.sync_client(), key, fromIndex, callback, recursive) {} -etcd::Watcher::Watcher(Client const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback): - Watcher(*client.sync_client(), key, range_end, fromIndex, callback) { -} +etcd::Watcher::Watcher(Client const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback) + : Watcher(*client.sync_client(), key, range_end, fromIndex, callback) {} // keepalive from then async client -etcd::KeepAlive::KeepAlive(Client const &client, int ttl, int64_t lease_id): - KeepAlive(*client.sync_client(), ttl, lease_id) { -} +etcd::KeepAlive::KeepAlive(Client const& client, int ttl, int64_t lease_id) + : KeepAlive(*client.sync_client(), ttl, lease_id) {} -etcd::KeepAlive::KeepAlive(Client const &client, - std::function const &handler, - int ttl, int64_t lease_id): - KeepAlive(*client.sync_client(), handler, ttl, lease_id) { -} +etcd::KeepAlive::KeepAlive( + Client const& client, + std::function const& handler, int ttl, + int64_t lease_id) + : KeepAlive(*client.sync_client(), handler, ttl, lease_id) {} diff --git a/src/KeepAlive.cpp b/src/KeepAlive.cpp index b1d21f1..c2d39f6 100644 --- a/src/KeepAlive.cpp +++ b/src/KeepAlive.cpp @@ -8,7 +8,7 @@ #include "proto/rpc.grpc.pb.h" namespace etcdv3 { - class AsyncLeaseKeepAliveAction; +class AsyncLeaseKeepAliveAction; } struct etcd::KeepAlive::EtcdServerStubs { @@ -16,15 +16,18 @@ struct etcd::KeepAlive::EtcdServerStubs { std::unique_ptr call; }; -void etcd::KeepAlive::EtcdServerStubsDeleter::operator()(etcd::KeepAlive::EtcdServerStubs *stubs) { +void etcd::KeepAlive::EtcdServerStubsDeleter::operator()( + etcd::KeepAlive::EtcdServerStubs* stubs) { if (stubs) { delete stubs; } } -etcd::KeepAlive::KeepAlive(SyncClient const &client, int ttl, int64_t lease_id): - ttl(ttl), lease_id(lease_id), continue_next(true), - grpc_timeout(client.get_grpc_timeout()) { +etcd::KeepAlive::KeepAlive(SyncClient const& client, int ttl, int64_t lease_id) + : ttl(ttl), + lease_id(lease_id), + continue_next(true), + grpc_timeout(client.get_grpc_timeout()) { stubs.reset(new EtcdServerStubs{}); stubs->leaseServiceStub = Lease::NewStub(client.grpc_channel()); @@ -41,38 +44,41 @@ etcd::KeepAlive::KeepAlive(SyncClient const &client, int ttl, int64_t lease_id): try { // start refresh this->refresh(); - } catch (const std::exception &e) { + } catch (const std::exception& e) { // propagate the exception eptr_ = std::current_exception(); } }); } -etcd::KeepAlive::KeepAlive(std::string const & address, int ttl, int64_t lease_id): - KeepAlive(SyncClient(address), ttl, lease_id) { -} - -etcd::KeepAlive::KeepAlive(std::string const & address, - std::string const & username, std::string const & password, - int ttl, int64_t lease_id, int const auth_token_ttl): - KeepAlive(SyncClient(address, username, password, auth_token_ttl), ttl, lease_id) { -} - -etcd::KeepAlive::KeepAlive(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::function const &handler, - int ttl, int64_t lease_id, - std::string const & target_name_override): - KeepAlive(SyncClient(address, ca, cert, privkey, target_name_override), ttl, lease_id) { -} - -etcd::KeepAlive::KeepAlive(SyncClient const &client, - std::function const &handler, - int ttl, int64_t lease_id): - handler_(handler), ttl(ttl), lease_id(lease_id), continue_next(true), - grpc_timeout(client.get_grpc_timeout()) { +etcd::KeepAlive::KeepAlive(std::string const& address, int ttl, + int64_t lease_id) + : KeepAlive(SyncClient(address), ttl, lease_id) {} + +etcd::KeepAlive::KeepAlive(std::string const& address, + std::string const& username, + std::string const& password, int ttl, + int64_t lease_id, int const auth_token_ttl) + : KeepAlive(SyncClient(address, username, password, auth_token_ttl), ttl, + lease_id) {} + +etcd::KeepAlive::KeepAlive( + std::string const& address, std::string const& ca, std::string const& cert, + std::string const& privkey, + std::function const& handler, int ttl, + int64_t lease_id, std::string const& target_name_override) + : KeepAlive(SyncClient(address, ca, cert, privkey, target_name_override), + ttl, lease_id) {} + +etcd::KeepAlive::KeepAlive( + SyncClient const& client, + std::function const& handler, int ttl, + int64_t lease_id) + : handler_(handler), + ttl(ttl), + lease_id(lease_id), + continue_next(true), + grpc_timeout(client.get_grpc_timeout()) { stubs.reset(new EtcdServerStubs{}); stubs->leaseServiceStub = Lease::NewStub(client.grpc_channel()); @@ -97,26 +103,23 @@ etcd::KeepAlive::KeepAlive(SyncClient const &client, }); } -etcd::KeepAlive::KeepAlive(std::string const & address, - std::function const &handler, - int ttl, int64_t lease_id): - KeepAlive(SyncClient(address), handler, ttl, lease_id) { -} +etcd::KeepAlive::KeepAlive( + std::string const& address, + std::function const& handler, int ttl, + int64_t lease_id) + : KeepAlive(SyncClient(address), handler, ttl, lease_id) {} -etcd::KeepAlive::KeepAlive(std::string const & address, - std::string const & username, std::string const & password, - std::function const &handler, - int ttl, int64_t lease_id, const int auth_token_ttl): - KeepAlive(SyncClient(address, username, password, auth_token_ttl), handler, ttl, lease_id) { -} +etcd::KeepAlive::KeepAlive( + std::string const& address, std::string const& username, + std::string const& password, + std::function const& handler, int ttl, + int64_t lease_id, const int auth_token_ttl) + : KeepAlive(SyncClient(address, username, password, auth_token_ttl), + handler, ttl, lease_id) {} -etcd::KeepAlive::~KeepAlive() -{ - this->Cancel(); -} +etcd::KeepAlive::~KeepAlive() { this->Cancel(); } -void etcd::KeepAlive::Cancel() -{ +void etcd::KeepAlive::Cancel() { if (!continue_next.exchange(false)) { return; } @@ -143,7 +146,8 @@ void etcd::KeepAlive::Check() { // run canceller first this->Cancel(); - // propagate the exception, as we throw in `Check()`, the `handler` won't be touched + // propagate the exception, as we throw in `Check()`, the `handler` won't be + // touched eptr_ = std::current_exception(); if (handler_) { handler_(eptr_); @@ -154,8 +158,7 @@ void etcd::KeepAlive::Check() { } } -void etcd::KeepAlive::refresh() -{ +void etcd::KeepAlive::refresh() { while (true) { if (!continue_next.load()) { return; @@ -164,7 +167,8 @@ void etcd::KeepAlive::refresh() int keepalive_ttl = std::max(ttl - 1, 1); { std::unique_lock lock(mutex_for_refresh_); - if (cv_for_refresh_.wait_for(lock, std::chrono::seconds(keepalive_ttl)) == std::cv_status::no_timeout) { + if (cv_for_refresh_.wait_for(lock, std::chrono::seconds(keepalive_ttl)) == + std::cv_status::no_timeout) { return; } } @@ -174,8 +178,7 @@ void etcd::KeepAlive::refresh() } } -void etcd::KeepAlive::refresh_once() -{ +void etcd::KeepAlive::refresh_once() { std::lock_guard scope_lock(mutex_for_refresh_); if (!continue_next.load()) { return; @@ -183,10 +186,12 @@ void etcd::KeepAlive::refresh_once() this->stubs->call->mutable_parameters().grpc_timeout = this->grpc_timeout; auto resp = this->stubs->call->Refresh(); if (!resp.is_ok()) { - throw std::runtime_error("Failed to refresh lease: error code: " + std::to_string(resp.error_code()) + - ", message: " + resp.error_message()); + throw std::runtime_error("Failed to refresh lease: error code: " + + std::to_string(resp.error_code()) + + ", message: " + resp.error_message()); } if (resp.value().ttl() == 0) { - throw std::out_of_range("Failed to refresh lease due to expiration: the new TTL is 0."); + throw std::out_of_range( + "Failed to refresh lease due to expiration: the new TTL is 0."); } } diff --git a/src/Response.cpp b/src/Response.cpp index 85624a3..26da605 100644 --- a/src/Response.cpp +++ b/src/Response.cpp @@ -3,13 +3,9 @@ #include -etcd::Response::Response() - : _error_code(0), - _index(0) -{ -} +etcd::Response::Response() : _error_code(0), _index(0) {} -etcd::Response::Response(const etcd::Response & response) { +etcd::Response::Response(const etcd::Response& response) { this->_error_code = response._error_code; this->_error_message = response._error_message; this->_index = response._index; @@ -20,7 +16,7 @@ etcd::Response::Response(const etcd::Response & response) { this->_keys = response._keys; this->_compact_revision = response._compact_revision; this->_lock_key = response._lock_key; - this->_name = response._name; + this->_name = response._name; this->_events = response._events; this->_duration = response._duration; @@ -31,23 +27,19 @@ etcd::Response::Response(const etcd::Response & response) { this->_leases = response._leases; } -etcd::Response::Response(const etcdv3::V3Response& reply, std::chrono::microseconds const& duration) -{ +etcd::Response::Response(const etcdv3::V3Response& reply, + std::chrono::microseconds const& duration) { _index = reply.get_index(); _action = reply.get_action(); _error_code = reply.get_error_code(); _error_message = reply.get_error_message(); - if(reply.has_values()) - { + if (reply.has_values()) { auto val = reply.get_values(); - for(unsigned int index = 0; index < val.size(); index++) - { + for (unsigned int index = 0; index < val.size(); index++) { _values.push_back(Value(val[index])); _keys.push_back(val[index].kvs.key()); } - } - else - { + } else { _value = Value(reply.get_value()); } _prev_value = Value(reply.get_prev_value()); @@ -57,7 +49,7 @@ etcd::Response::Response(const etcdv3::V3Response& reply, std::chrono::microseco _lock_key = reply.get_lock_key(); _name = reply.get_name(); - for (auto const &ev: reply.get_events()) { + for (auto const& ev : reply.get_events()) { _events.emplace_back(etcd::Event(ev)); } @@ -74,103 +66,54 @@ etcd::Response::Response(const etcdv3::V3Response& reply, std::chrono::microseco } etcd::Response::Response(int error_code, std::string const& error_message) - : _error_code(error_code), - _error_message(error_message), - _index(0) -{ -} + : _error_code(error_code), _error_message(error_message), _index(0) {} -etcd::Response::Response(int error_code, char const * error_message) - : _error_code(error_code), - _error_message(error_message), - _index(0) -{ -} +etcd::Response::Response(int error_code, char const* error_message) + : _error_code(error_code), _error_message(error_message), _index(0) {} -int etcd::Response::error_code() const -{ - return _error_code; -} +int etcd::Response::error_code() const { return _error_code; } -std::string const & etcd::Response::error_message() const -{ +std::string const& etcd::Response::error_message() const { return _error_message; } -bool etcd::Response::is_ok() const -{ - return error_code() == 0; -} +bool etcd::Response::is_ok() const { return error_code() == 0; } -bool etcd::Response::is_network_unavailable() const -{ +bool etcd::Response::is_network_unavailable() const { return error_code() == ::grpc::StatusCode::UNAVAILABLE; } -bool etcd::Response::is_grpc_timeout() const -{ +bool etcd::Response::is_grpc_timeout() const { return _error_code == grpc::StatusCode::DEADLINE_EXCEEDED; } -std::string const & etcd::Response::action() const -{ - return _action; -} +std::string const& etcd::Response::action() const { return _action; } -int64_t etcd::Response::index() const -{ - return _index; -} +int64_t etcd::Response::index() const { return _index; } -etcd::Value const & etcd::Response::value() const -{ - return _value; -} +etcd::Value const& etcd::Response::value() const { return _value; } -etcd::Value const & etcd::Response::prev_value() const -{ - return _prev_value; -} +etcd::Value const& etcd::Response::prev_value() const { return _prev_value; } -etcd::Values const & etcd::Response::values() const -{ - return _values; -} +etcd::Values const& etcd::Response::values() const { return _values; } -etcd::Value const & etcd::Response::value(int index) const -{ +etcd::Value const& etcd::Response::value(int index) const { return _values[index]; } -etcd::Keys const & etcd::Response::keys() const -{ - return _keys; -} +etcd::Keys const& etcd::Response::keys() const { return _keys; } -std::string const & etcd::Response::key(int index) const -{ - return _keys[index]; -} +std::string const& etcd::Response::key(int index) const { return _keys[index]; } -int64_t etcd::Response::compact_revision() const -{ - return _compact_revision; -} +int64_t etcd::Response::compact_revision() const { return _compact_revision; } -int64_t etcd::Response::watch_id() const -{ - return _watch_id; -} +int64_t etcd::Response::watch_id() const { return _watch_id; } -std::string const & etcd::Response::lock_key() const { - return _lock_key; -} +std::string const& etcd::Response::lock_key() const { return _lock_key; } -std::string const & etcd::Response::name() const { - return _name; -} +std::string const& etcd::Response::name() const { return _name; } -std::vector const & etcd::Response::events() const { +std::vector const& etcd::Response::events() const { return this->_events; } @@ -178,18 +121,12 @@ std::chrono::microseconds const& etcd::Response::duration() const { return this->_duration; } -uint64_t etcd::Response::cluster_id() const { - return this->_cluster_id; -} +uint64_t etcd::Response::cluster_id() const { return this->_cluster_id; } -uint64_t etcd::Response::member_id() const { - return this->_member_id; -} +uint64_t etcd::Response::member_id() const { return this->_member_id; } -uint64_t etcd::Response::raft_term() const { - return this->_raft_term; -} +uint64_t etcd::Response::raft_term() const { return this->_raft_term; } -std::vector const & etcd::Response::leases() const { +std::vector const& etcd::Response::leases() const { return this->_leases; } diff --git a/src/SyncClient.cpp b/src/SyncClient.cpp index 495ed8c..96dfbd3 100644 --- a/src/SyncClient.cpp +++ b/src/SyncClient.cpp @@ -1,5 +1,6 @@ #if defined(_WIN32) -// see also: https://stackoverflow.com/questions/2561368/illegal-token-on-right-side-of +// see also: +// https://stackoverflow.com/questions/2561368/illegal-token-on-right-side-of #define NOMINMAX #endif @@ -20,8 +21,8 @@ #endif #include -#include #include +#include #include #include #include @@ -34,35 +35,38 @@ #include #include "proto/rpc.grpc.pb.h" -#include "proto/v3lock.grpc.pb.h" #include "proto/v3election.grpc.pb.h" +#include "proto/v3lock.grpc.pb.h" -#include "etcd/SyncClient.hpp" #include "etcd/KeepAlive.hpp" -#include "etcd/v3/action_constants.hpp" +#include "etcd/SyncClient.hpp" #include "etcd/v3/Action.hpp" #include "etcd/v3/AsyncGRPC.hpp" #include "etcd/v3/Transaction.hpp" +#include "etcd/v3/action_constants.hpp" namespace etcd { namespace detail { -static void string_split(std::vector &dests, std::string const &src, std::string const &seps) { +static void string_split(std::vector& dests, + std::string const& src, std::string const& seps) { dests.clear(); std::string::const_iterator start = src.begin(); std::string::const_iterator end = src.end(); - std::string::const_iterator next = std::find_first_of(start, end, seps.begin(), seps.end()); + std::string::const_iterator next = + std::find_first_of(start, end, seps.begin(), seps.end()); while (next != end) { - dests.push_back(std::string(start, next)); - start = next + 1; - next = std::find_first_of(start, end, seps.begin(), seps.end()); + dests.push_back(std::string(start, next)); + start = next + 1; + next = std::find_first_of(start, end, seps.begin(), seps.end()); } if (start != end) { dests.push_back(std::string(start, end)); } } -static std::string string_join(std::vector const &srcs, std::string const sep) { +static std::string string_join(std::vector const& srcs, + std::string const sep) { std::stringstream ss; if (!srcs.empty()) { ss << srcs[0]; @@ -73,7 +77,8 @@ static std::string string_join(std::vector const &srcs, std::string return ss.str(); } -static bool dns_resolve(std::string const &target, std::vector &endpoints) { +static bool dns_resolve(std::string const& target, + std::vector& endpoints) { struct addrinfo hints = {}, *addrs; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; @@ -101,7 +106,8 @@ static bool dns_resolve(std::string const &target, std::vector &end } #endif - int r = getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs); + int r = getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, + &addrs); if (r != 0) { std::cerr << "warn: getaddrinfo() failed for endpoint " << target << " with error: " << r << std::endl; @@ -111,23 +117,25 @@ static bool dns_resolve(std::string const &target, std::vector &end char host[16] = {'\0'}; for (struct addrinfo* addr = addrs; addr != nullptr; addr = addr->ai_next) { memset(host, '\0', sizeof(host)); - getnameinfo(addr->ai_addr, addr->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); + getnameinfo(addr->ai_addr, addr->ai_addrlen, host, sizeof(host), NULL, 0, + NI_NUMERICHOST); endpoints.emplace_back(std::string(host) + ":" + target_parts[1]); } freeaddrinfo(addrs); return true; } -const std::string strip_and_resolve_addresses(std::string const &address) { +const std::string strip_and_resolve_addresses(std::string const& address) { std::vector addresses; string_split(addresses, address, ",;"); std::string stripped_address; { std::vector stripped_addresses; std::string substr("://"); - for (auto const &addr: addresses) { + for (auto const& addr : addresses) { std::string::size_type idx = addr.find(substr); - std::string target = idx == std::string::npos ? addr : addr.substr(idx + substr.length()); + std::string target = + idx == std::string::npos ? addr : addr.substr(idx + substr.length()); etcd::detail::dns_resolve(target, stripped_addresses); } stripped_address = string_join(stripped_addresses, ","); @@ -135,10 +143,10 @@ const std::string strip_and_resolve_addresses(std::string const &address) { return "ipv4:///" + stripped_address; } -const bool authenticate(std::shared_ptr const &channel, - std::string const &username, - std::string const &password, - std::string &token_or_message) { +const bool authenticate(std::shared_ptr const& channel, + std::string const& username, + std::string const& password, + std::string& token_or_message) { // run a round of auth auto auth_stub = etcdserverpb::Auth::NewStub(channel); ClientContext context; @@ -156,23 +164,22 @@ const bool authenticate(std::shared_ptr const &channel, } } -static std::string read_from_file(std::string const &filename) { +static std::string read_from_file(std::string const& filename) { std::ifstream file(filename.c_str(), std::ios::in); if (file.is_open()) { std::stringstream ss; - ss << file.rdbuf (); - file.close (); - return ss.str (); + ss << file.rdbuf(); + file.close(); + return ss.str(); } else { std::cerr << "[ERROR] failed to load given file '" << filename << "', " - << strerror(errno) - << std::endl; + << strerror(errno) << std::endl; } return std::string{}; } static grpc::SslCredentialsOptions make_ssl_credentials( - std::string const &ca, std::string const &cert, std::string const &key) { + std::string const& ca, std::string const& cert, std::string const& key) { grpc::SslCredentialsOptions options; options.pem_root_certs = read_from_file(ca); options.pem_cert_chain = read_from_file(cert); @@ -180,59 +187,64 @@ static grpc::SslCredentialsOptions make_ssl_credentials( return options; } -template +template std::unique_ptr make_unique_ptr(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); + return std::unique_ptr(new T(std::forward(args)...)); } -} -} +} // namespace detail +} // namespace etcd class etcd::SyncClient::TokenAuthenticator { - private: - std::shared_ptr channel_; - std::string username_, password_, token_; - int ttl_ = 300; // see also --auth-token-ttl for etcd - std::chrono::time_point updated_at; - std::mutex mtx_; - bool has_token_ = false; - - public: - TokenAuthenticator(): has_token_(false) { + private: + std::shared_ptr channel_; + std::string username_, password_, token_; + int ttl_ = 300; // see also --auth-token-ttl for etcd + std::chrono::time_point updated_at; + std::mutex mtx_; + bool has_token_ = false; + + public: + TokenAuthenticator() : has_token_(false) {} + + TokenAuthenticator(std::shared_ptr channel, + std::string const& username, std::string const& password, + const int ttl = 300) + : channel_(channel), + username_(username), + password_(password), + ttl_(ttl), + has_token_(false) { + if ((!username.empty()) && (!(password.empty()))) { + has_token_ = true; + renew_if_expired(true); } + } - TokenAuthenticator(std::shared_ptr channel, - std::string const &username, - std::string const &password, - const int ttl=300) - : channel_(channel), username_(username), password_(password), ttl_(ttl), has_token_(false) { - if ((!username.empty()) && (!(password.empty()))) { - has_token_ = true; - renew_if_expired(true); - } + std::string const& renew_if_expired(const bool force = false) { + if (!has_token_) { + return token_; } - - std::string const &renew_if_expired(const bool force = false) { - if (!has_token_) { - return token_; - } - std::lock_guard scoped_lock(mtx_); - if (force || (!token_.empty())) { - auto tp = std::chrono::system_clock::now(); - if (force || std::chrono::duration_cast(tp - updated_at).count() - > std::max(1, ttl_ - 3)) { - updated_at = tp; - // auth - if (!etcd::detail::authenticate(this->channel_, username_, password_, token_)) { - throw std::invalid_argument("Etcd authentication failed: " + token_); - } + std::lock_guard scoped_lock(mtx_); + if (force || (!token_.empty())) { + auto tp = std::chrono::system_clock::now(); + if (force || + std::chrono::duration_cast(tp - updated_at) + .count() > std::max(1, ttl_ - 3)) { + updated_at = tp; + // auth + if (!etcd::detail::authenticate(this->channel_, username_, password_, + token_)) { + throw std::invalid_argument("Etcd authentication failed: " + token_); } } - return token_; } + return token_; + } }; -void etcd::SyncClient::TokenAuthenticatorDeleter::operator()(etcd::SyncClient::TokenAuthenticator *authenticator) { +void etcd::SyncClient::TokenAuthenticatorDeleter::operator()( + etcd::SyncClient::TokenAuthenticator* authenticator) { if (authenticator) { delete authenticator; } @@ -246,21 +258,23 @@ struct etcd::SyncClient::EtcdServerStubs { std::unique_ptr electionServiceStub; }; -void etcd::SyncClient::EtcdServerStubsDeleter::operator()(etcd::SyncClient::EtcdServerStubs *stubs) { +void etcd::SyncClient::EtcdServerStubsDeleter::operator()( + etcd::SyncClient::EtcdServerStubs* stubs) { if (stubs) { delete stubs; } } -etcd::SyncClient::SyncClient(std::string const & address, - std::string const & load_balancer) -{ +etcd::SyncClient::SyncClient(std::string const& address, + std::string const& load_balancer) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); - std::shared_ptr creds = grpc::InsecureChannelCredentials(); + std::shared_ptr creds = + grpc::InsecureChannelCredentials(); grpc_args.SetLoadBalancingPolicyName(load_balancer); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); this->token_authenticator.reset(new TokenAuthenticator()); @@ -268,122 +282,126 @@ etcd::SyncClient::SyncClient(std::string const & address, // create stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient::SyncClient(std::string const & address, - grpc::ChannelArguments const & arguments) -{ +etcd::SyncClient::SyncClient(std::string const& address, + grpc::ChannelArguments const& arguments) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args = arguments; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); - std::shared_ptr creds = grpc::InsecureChannelCredentials(); + std::shared_ptr creds = + grpc::InsecureChannelCredentials(); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); this->token_authenticator.reset(new TokenAuthenticator()); // create stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient *etcd::SyncClient::WithUrl(std::string const & etcd_url, - std::string const & load_balancer) { +etcd::SyncClient* etcd::SyncClient::WithUrl(std::string const& etcd_url, + std::string const& load_balancer) { return new etcd::SyncClient(etcd_url, load_balancer); } -etcd::SyncClient *etcd::SyncClient::WithUrl(std::string const & etcd_url, - grpc::ChannelArguments const & arguments) { +etcd::SyncClient* etcd::SyncClient::WithUrl( + std::string const& etcd_url, grpc::ChannelArguments const& arguments) { return new etcd::SyncClient(etcd_url, arguments); } -etcd::SyncClient::SyncClient(std::string const & address, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - std::string const & load_balancer) -{ +etcd::SyncClient::SyncClient(std::string const& address, + std::string const& username, + std::string const& password, + int const auth_token_ttl, + std::string const& load_balancer) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); - std::shared_ptr creds = grpc::InsecureChannelCredentials(); + std::shared_ptr creds = + grpc::InsecureChannelCredentials(); grpc_args.SetLoadBalancingPolicyName(load_balancer); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); // auth - this->token_authenticator.reset(new TokenAuthenticator(this->channel, username, password, auth_token_ttl)); + this->token_authenticator.reset(new TokenAuthenticator( + this->channel, username, password, auth_token_ttl)); // setup stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient::SyncClient(std::string const & address, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - grpc::ChannelArguments const & arguments) -{ +etcd::SyncClient::SyncClient(std::string const& address, + std::string const& username, + std::string const& password, + int const auth_token_ttl, + grpc::ChannelArguments const& arguments) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args = arguments; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); - std::shared_ptr creds = grpc::InsecureChannelCredentials(); + std::shared_ptr creds = + grpc::InsecureChannelCredentials(); this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); // auth - this->token_authenticator.reset(new TokenAuthenticator(this->channel, username, password, auth_token_ttl)); + this->token_authenticator.reset(new TokenAuthenticator( + this->channel, username, password, auth_token_ttl)); // setup stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient *etcd::SyncClient::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - std::string const & load_balancer) { - return new etcd::SyncClient(etcd_url, username, password, auth_token_ttl, load_balancer); +etcd::SyncClient* etcd::SyncClient::WithUser(std::string const& etcd_url, + std::string const& username, + std::string const& password, + int const auth_token_ttl, + std::string const& load_balancer) { + return new etcd::SyncClient(etcd_url, username, password, auth_token_ttl, + load_balancer); } -etcd::SyncClient *etcd::SyncClient::WithUser(std::string const & etcd_url, - std::string const & username, - std::string const & password, - int const auth_token_ttl, - grpc::ChannelArguments const & arguments) { - return new etcd::SyncClient(etcd_url, username, password, auth_token_ttl, arguments); +etcd::SyncClient* etcd::SyncClient::WithUser( + std::string const& etcd_url, std::string const& username, + std::string const& password, int const auth_token_ttl, + grpc::ChannelArguments const& arguments) { + return new etcd::SyncClient(etcd_url, username, password, auth_token_ttl, + arguments); } - -etcd::SyncClient::SyncClient(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer) -{ +etcd::SyncClient::SyncClient(std::string const& address, std::string const& ca, + std::string const& cert, + std::string const& privkey, + std::string const& target_name_override, + std::string const& load_balancer) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); @@ -391,7 +409,8 @@ etcd::SyncClient::SyncClient(std::string const & address, etcd::detail::make_ssl_credentials(ca, cert, privkey)); grpc_args.SetLoadBalancingPolicyName(load_balancer); if (!target_name_override.empty()) { - grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name_override); + grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + target_name_override); } this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); this->token_authenticator.reset(new TokenAuthenticator()); @@ -399,28 +418,28 @@ etcd::SyncClient::SyncClient(std::string const & address, // setup stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient::SyncClient(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - grpc::ChannelArguments const & arguments) -{ +etcd::SyncClient::SyncClient(std::string const& address, std::string const& ca, + std::string const& cert, + std::string const& privkey, + std::string const& target_name_override, + grpc::ChannelArguments const& arguments) { // create channels - std::string const addresses = etcd::detail::strip_and_resolve_addresses(address); + std::string const addresses = + etcd::detail::strip_and_resolve_addresses(address); grpc::ChannelArguments grpc_args = arguments; grpc_args.SetMaxSendMessageSize(std::numeric_limits::max()); grpc_args.SetMaxReceiveMessageSize(std::numeric_limits::max()); std::shared_ptr creds = grpc::SslCredentials( etcd::detail::make_ssl_credentials(ca, cert, privkey)); if (!target_name_override.empty()) { - grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, target_name_override); + grpc_args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + target_name_override); } this->channel = grpc::CreateCustomChannel(addresses, creds, grpc_args); this->token_authenticator.reset(new TokenAuthenticator()); @@ -428,28 +447,26 @@ etcd::SyncClient::SyncClient(std::string const & address, // setup stubs stubs.reset(new EtcdServerStubs{}); stubs->kvServiceStub = KV::NewStub(this->channel); - stubs->watchServiceStub= Watch::NewStub(this->channel); - stubs->leaseServiceStub= Lease::NewStub(this->channel); + stubs->watchServiceStub = Watch::NewStub(this->channel); + stubs->leaseServiceStub = Lease::NewStub(this->channel); stubs->lockServiceStub = Lock::NewStub(this->channel); stubs->electionServiceStub = Election::NewStub(this->channel); } -etcd::SyncClient *etcd::SyncClient::WithSSL(std::string const & etcd_url, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override, - std::string const & load_balancer) { - return new etcd::SyncClient(etcd_url, ca, cert, privkey, target_name_override, load_balancer); +etcd::SyncClient* etcd::SyncClient::WithSSL( + std::string const& etcd_url, std::string const& ca, std::string const& cert, + std::string const& privkey, std::string const& target_name_override, + std::string const& load_balancer) { + return new etcd::SyncClient(etcd_url, ca, cert, privkey, target_name_override, + load_balancer); } -etcd::SyncClient *etcd::SyncClient::WithSSL(std::string const & etcd_url, - grpc::ChannelArguments const & arguments, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & target_name_override) { - return new etcd::SyncClient(etcd_url, ca, cert, privkey, target_name_override, arguments); +etcd::SyncClient* etcd::SyncClient::WithSSL( + std::string const& etcd_url, grpc::ChannelArguments const& arguments, + std::string const& ca, std::string const& cert, std::string const& privkey, + std::string const& target_name_override) { + return new etcd::SyncClient(etcd_url, ca, cert, privkey, target_name_override, + arguments); } etcd::SyncClient::~SyncClient() { @@ -460,11 +477,11 @@ etcd::SyncClient::~SyncClient() { /** * Note [lease with TTL and issue the actual request] * - * We sometime use the request like `set(key, value, TTL)`, we explain the TTL as - * the time between the user call the `set()` method between the request is - * actually executed in etcd server. Thus, we issue a lease request with that TTL - * value immediately, and pass it to the `set_internal()` method, the later may - * be issues asynchronously. + * We sometime use the request like `set(key, value, TTL)`, we explain the TTL + * as the time between the user call the `set()` method between the request is + * actually executed in etcd server. Thus, we issue a lease request with that + * TTL value immediately, and pass it to the `set_internal()` method, the later + * may be issues asynchronously. * * Thus the TTL could keep the expected semantic even in the async runtime. */ @@ -473,8 +490,7 @@ etcd::Response etcd::SyncClient::head() { return Response::create(this->head_internal()); } -std::shared_ptr etcd::SyncClient::head_internal() -{ +std::shared_ptr etcd::SyncClient::head_internal() { etcdv3::ActionParameters params; params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; @@ -482,16 +498,16 @@ std::shared_ptr etcd::SyncClient::head_internal() return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::get(std::string const &key) { +etcd::Response etcd::SyncClient::get(std::string const& key) { return Response::create(this->get_internal(key)); } -etcd::Response etcd::SyncClient::get(std::string const &key, int64_t revision) { +etcd::Response etcd::SyncClient::get(std::string const& key, int64_t revision) { return Response::create(this->get_internal(key, revision)); } -std::shared_ptr etcd::SyncClient::get_internal(std::string const & key, int64_t revision) -{ +std::shared_ptr etcd::SyncClient::get_internal( + std::string const& key, int64_t revision) { etcdv3::ActionParameters params; params.key.assign(key); params.revision = revision; @@ -502,31 +518,29 @@ std::shared_ptr etcd::SyncClient::get_internal(std::st return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::set(std::string const & key, std::string const & value, int ttl) -{ +etcd::Response etcd::SyncClient::set(std::string const& key, + std::string const& value, int ttl) { // See Note [lease with TTL and issue the actual request] int64_t leaseId = 0; - if(ttl > 0) - { + if (ttl > 0) { auto res = this->leasegrant(ttl); - if(!res.is_ok()) - { + if (!res.is_ok()) { return etcd::Response(res.error_code(), res.error_message()); - } - else - { + } else { leaseId = res.value().lease(); } } return Response::create(this->set_internal(key, value, leaseId)); } -etcd::Response etcd::SyncClient::set(std::string const & key, std::string const & value, int64_t leaseid) -{ +etcd::Response etcd::SyncClient::set(std::string const& key, + std::string const& value, + int64_t leaseid) { return Response::create(this->set_internal(key, value, leaseid)); } -std::shared_ptr etcd::SyncClient::set_internal(std::string const & key, std::string const & value, int64_t leaseid) { +std::shared_ptr etcd::SyncClient::set_internal( + std::string const& key, std::string const& value, int64_t leaseid) { etcdv3::ActionParameters params; params.key.assign(key); params.value.assign(value); @@ -537,31 +551,29 @@ std::shared_ptr etcd::SyncClient::set_internal(std::stri return std::make_shared(std::move(params), false); } -etcd::Response etcd::SyncClient::add(std::string const & key, std::string const & value, int ttl) -{ +etcd::Response etcd::SyncClient::add(std::string const& key, + std::string const& value, int ttl) { // See Note [lease with TTL and issue the actual request] int64_t leaseId = 0; - if(ttl > 0) - { + if (ttl > 0) { auto res = this->leasegrant(ttl); - if(!res.is_ok()) - { + if (!res.is_ok()) { return etcd::Response(res.error_code(), res.error_message()); - } - else - { + } else { leaseId = res.value().lease(); } } return Response::create(this->add_internal(key, value, leaseId)); } -etcd::Response etcd::SyncClient::add(std::string const & key, std::string const & value, int64_t leaseid) -{ +etcd::Response etcd::SyncClient::add(std::string const& key, + std::string const& value, + int64_t leaseid) { return Response::create(this->add_internal(key, value, leaseid)); } -std::shared_ptr etcd::SyncClient::add_internal(std::string const & key, std::string const & value, int64_t leaseid) { +std::shared_ptr etcd::SyncClient::add_internal( + std::string const& key, std::string const& value, int64_t leaseid) { etcdv3::ActionParameters params; params.key.assign(key); params.value.assign(value); @@ -572,11 +584,13 @@ std::shared_ptr etcd::SyncClient::add_internal(std::stri return std::make_shared(std::move(params), true); } -etcd::Response etcd::SyncClient::put(std::string const & key, std::string const & value) { +etcd::Response etcd::SyncClient::put(std::string const& key, + std::string const& value) { return Response::create(this->put_internal(key, value)); } -std::shared_ptr etcd::SyncClient::put_internal(std::string const & key, std::string const & value) { +std::shared_ptr etcd::SyncClient::put_internal( + std::string const& key, std::string const& value) { etcdv3::ActionParameters params; params.key.assign(key); params.value.assign(value); @@ -586,31 +600,29 @@ std::shared_ptr etcd::SyncClient::put_internal(std::stri return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::modify(std::string const & key, std::string const & value, int ttl) -{ +etcd::Response etcd::SyncClient::modify(std::string const& key, + std::string const& value, int ttl) { // See Note [lease with TTL and issue the actual request] int64_t leaseId = 0; - if(ttl > 0) - { + if (ttl > 0) { auto res = leasegrant(ttl); - if(!res.is_ok()) - { - return etcd::Response(res.error_code(), res.error_message()); - } - else - { + if (!res.is_ok()) { + return etcd::Response(res.error_code(), res.error_message()); + } else { leaseId = res.value().lease(); } } return Response::create(this->modify_internal(key, value, leaseId)); } -etcd::Response etcd::SyncClient::modify(std::string const & key, std::string const & value, int64_t leaseid) -{ +etcd::Response etcd::SyncClient::modify(std::string const& key, + std::string const& value, + int64_t leaseid) { return Response::create(this->modify_internal(key, value, leaseid)); } -std::shared_ptr etcd::SyncClient::modify_internal(std::string const & key, std::string const & value, int64_t leaseid) { +std::shared_ptr etcd::SyncClient::modify_internal( + std::string const& key, std::string const& value, int64_t leaseid) { etcdv3::ActionParameters params; params.key.assign(key); params.value.assign(value); @@ -621,55 +633,61 @@ std::shared_ptr etcd::SyncClient::modify_internal(std return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int ttl) -{ +etcd::Response etcd::SyncClient::modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, + int ttl) { // See Note [lease with TTL and issue the actual request] int64_t leaseId = 0; - if(ttl > 0) - { + if (ttl > 0) { auto res = leasegrant(ttl); - if(!res.is_ok()) - { - return etcd::Response(res.error_code(), res.error_message()); - } - else - { + if (!res.is_ok()) { + return etcd::Response(res.error_code(), res.error_message()); + } else { leaseId = res.value().lease(); } } - return Response::create(this->modify_if_internal(key, value, 0, old_value, leaseId, etcdv3::AtomicityType::PREV_VALUE)); + return Response::create(this->modify_if_internal( + key, value, 0, old_value, leaseId, etcdv3::AtomicityType::PREV_VALUE)); } -etcd::Response etcd::SyncClient::modify_if(std::string const & key, std::string const & value, std::string const & old_value, int64_t leaseid) -{ - return Response::create(this->modify_if_internal(key, value, 0, old_value, leaseid, etcdv3::AtomicityType::PREV_VALUE)); +etcd::Response etcd::SyncClient::modify_if(std::string const& key, + std::string const& value, + std::string const& old_value, + int64_t leaseid) { + return Response::create(this->modify_if_internal( + key, value, 0, old_value, leaseid, etcdv3::AtomicityType::PREV_VALUE)); } -etcd::Response etcd::SyncClient::modify_if(std::string const & key, std::string const & value, int64_t old_index, int ttl) -{ +etcd::Response etcd::SyncClient::modify_if(std::string const& key, + std::string const& value, + int64_t old_index, int ttl) { // See Note [lease with TTL and issue the actual request] int64_t leaseId = 0; - if(ttl > 0) - { + if (ttl > 0) { auto res = leasegrant(ttl); - if(!res.is_ok()) - { - return etcd::Response(res.error_code(), res.error_message()); - } - else - { + if (!res.is_ok()) { + return etcd::Response(res.error_code(), res.error_message()); + } else { leaseId = res.value().lease(); } } - return Response::create(this->modify_if_internal(key, value, old_index, "", leaseId, etcdv3::AtomicityType::PREV_INDEX)); + return Response::create(this->modify_if_internal( + key, value, old_index, "", leaseId, etcdv3::AtomicityType::PREV_INDEX)); } -etcd::Response etcd::SyncClient::modify_if(std::string const & key, std::string const & value, int64_t old_index, int64_t leaseid) -{ - return Response::create(this->modify_if_internal(key, value, old_index, "", leaseid, etcdv3::AtomicityType::PREV_INDEX)); +etcd::Response etcd::SyncClient::modify_if(std::string const& key, + std::string const& value, + int64_t old_index, int64_t leaseid) { + return Response::create(this->modify_if_internal( + key, value, old_index, "", leaseid, etcdv3::AtomicityType::PREV_INDEX)); } -std::shared_ptr etcd::SyncClient::modify_if_internal(std::string const & key, std::string const & value, int64_t old_index, std::string const & old_value, int64_t leaseId, etcdv3::AtomicityType const & atomicity_type) { +std::shared_ptr +etcd::SyncClient::modify_if_internal( + std::string const& key, std::string const& value, int64_t old_index, + std::string const& old_value, int64_t leaseId, + etcdv3::AtomicityType const& atomicity_type) { etcdv3::ActionParameters params; params.key.assign(key); params.value.assign(value); @@ -679,15 +697,16 @@ std::shared_ptr etcd::SyncClient::modify_if_i params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; params.kv_stub = stubs->kvServiceStub.get(); - return std::make_shared(std::move(params), atomicity_type); + return std::make_shared(std::move(params), + atomicity_type); } -etcd::Response etcd::SyncClient::rm(std::string const & key) -{ +etcd::Response etcd::SyncClient::rm(std::string const& key) { return Response::create(this->rm_internal(key)); } -std::shared_ptr etcd::SyncClient::rm_internal(std::string const & key) { +std::shared_ptr etcd::SyncClient::rm_internal( + std::string const& key) { etcdv3::ActionParameters params; params.key.assign(key); params.withPrefix = false; @@ -697,17 +716,22 @@ std::shared_ptr etcd::SyncClient::rm_internal(std::st return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::rm_if(std::string const & key, std::string const & old_value) -{ - return Response::create(this->rm_if_internal(key, 0, old_value, etcdv3::AtomicityType::PREV_VALUE)); +etcd::Response etcd::SyncClient::rm_if(std::string const& key, + std::string const& old_value) { + return Response::create(this->rm_if_internal( + key, 0, old_value, etcdv3::AtomicityType::PREV_VALUE)); } -etcd::Response etcd::SyncClient::rm_if(std::string const & key, int64_t old_index) -{ - return Response::create(this->rm_if_internal(key, old_index, "", etcdv3::AtomicityType::PREV_INDEX)); +etcd::Response etcd::SyncClient::rm_if(std::string const& key, + int64_t old_index) { + return Response::create(this->rm_if_internal( + key, old_index, "", etcdv3::AtomicityType::PREV_INDEX)); } -std::shared_ptr etcd::SyncClient::rm_if_internal(std::string const & key, int64_t old_index, const std::string & old_value, etcdv3::AtomicityType const & atomicity_type) { +std::shared_ptr +etcd::SyncClient::rm_if_internal(std::string const& key, int64_t old_index, + const std::string& old_value, + etcdv3::AtomicityType const& atomicity_type) { etcdv3::ActionParameters params; params.key.assign(key); params.withPrefix = false; @@ -716,15 +740,16 @@ std::shared_ptr etcd::SyncClient::rm_if_int params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; params.kv_stub = stubs->kvServiceStub.get(); - return std::make_shared(std::move(params), atomicity_type); + return std::make_shared( + std::move(params), atomicity_type); } -etcd::Response etcd::SyncClient::rmdir(std::string const & key, bool recursive) -{ +etcd::Response etcd::SyncClient::rmdir(std::string const& key, bool recursive) { return Response::create(this->rmdir_internal(key, recursive)); } -std::shared_ptr etcd::SyncClient::rmdir_internal(std::string const & key, bool recursive) { +std::shared_ptr etcd::SyncClient::rmdir_internal( + std::string const& key, bool recursive) { etcdv3::ActionParameters params; params.key.assign(key); params.withPrefix = recursive; @@ -734,17 +759,18 @@ std::shared_ptr etcd::SyncClient::rmdir_internal(std: return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::rmdir(std::string const & key, const char *range_end) -{ +etcd::Response etcd::SyncClient::rmdir(std::string const& key, + const char* range_end) { return rmdir(key, std::string(range_end)); } -etcd::Response etcd::SyncClient::rmdir(std::string const & key, std::string const &range_end) -{ +etcd::Response etcd::SyncClient::rmdir(std::string const& key, + std::string const& range_end) { return Response::create(this->rmdir_internal(key, range_end)); } -std::shared_ptr etcd::SyncClient::rmdir_internal(std::string const & key, std::string const &range_end) { +std::shared_ptr etcd::SyncClient::rmdir_internal( + std::string const& key, std::string const& range_end) { etcdv3::ActionParameters params; params.key.assign(key); params.range_end.assign(range_end); @@ -755,67 +781,76 @@ std::shared_ptr etcd::SyncClient::rmdir_internal(std: return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::ls(std::string const & key) -{ +etcd::Response etcd::SyncClient::ls(std::string const& key) { return Response::create(this->ls_internal(key, 0 /* default: no limit */)); } -etcd::Response etcd::SyncClient::ls(std::string const & key, size_t const limit) -{ +etcd::Response etcd::SyncClient::ls(std::string const& key, + size_t const limit) { return Response::create(this->ls_internal(key, limit)); } -etcd::Response etcd::SyncClient::ls(std::string const & key, size_t const limit, int64_t revision) -{ +etcd::Response etcd::SyncClient::ls(std::string const& key, size_t const limit, + int64_t revision) { return Response::create(this->ls_internal(key, limit, false, revision)); } -etcd::Response etcd::SyncClient::ls(std::string const & key, std::string const &range_end) -{ - return Response::create(this->ls_internal(key, range_end, 0 /* default: no limit */)); +etcd::Response etcd::SyncClient::ls(std::string const& key, + std::string const& range_end) { + return Response::create( + this->ls_internal(key, range_end, 0 /* default: no limit */)); } -etcd::Response etcd::SyncClient::ls(std::string const & key, std::string const &range_end, size_t const limit) -{ +etcd::Response etcd::SyncClient::ls(std::string const& key, + std::string const& range_end, + size_t const limit) { return Response::create(this->ls_internal(key, range_end, limit)); } -etcd::Response etcd::SyncClient::ls(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision) -{ - return Response::create(this->ls_internal(key, range_end, limit, false, revision)); +etcd::Response etcd::SyncClient::ls(std::string const& key, + std::string const& range_end, + size_t const limit, int64_t revision) { + return Response::create( + this->ls_internal(key, range_end, limit, false, revision)); } -etcd::Response etcd::SyncClient::keys(std::string const & key) -{ - return Response::create(this->ls_internal(key, 0 /* default: no limit */, true)); +etcd::Response etcd::SyncClient::keys(std::string const& key) { + return Response::create( + this->ls_internal(key, 0 /* default: no limit */, true)); } -etcd::Response etcd::SyncClient::keys(std::string const & key, size_t const limit) -{ +etcd::Response etcd::SyncClient::keys(std::string const& key, + size_t const limit) { return Response::create(this->ls_internal(key, limit, true)); } -etcd::Response etcd::SyncClient::keys(std::string const & key, size_t const limit, int64_t revision) -{ +etcd::Response etcd::SyncClient::keys(std::string const& key, + size_t const limit, int64_t revision) { return Response::create(this->ls_internal(key, limit, true, revision)); } -etcd::Response etcd::SyncClient::keys(std::string const & key, std::string const &range_end) -{ - return Response::create(this->ls_internal(key, range_end, 0 /* default: no limit */, true)); +etcd::Response etcd::SyncClient::keys(std::string const& key, + std::string const& range_end) { + return Response::create( + this->ls_internal(key, range_end, 0 /* default: no limit */, true)); } -etcd::Response etcd::SyncClient::keys(std::string const & key, std::string const &range_end, size_t const limit) -{ +etcd::Response etcd::SyncClient::keys(std::string const& key, + std::string const& range_end, + size_t const limit) { return Response::create(this->ls_internal(key, range_end, limit, true)); } -etcd::Response etcd::SyncClient::keys(std::string const & key, std::string const &range_end, size_t const limit, int64_t revision) -{ - return Response::create(this->ls_internal(key, range_end, limit, true, revision)); +etcd::Response etcd::SyncClient::keys(std::string const& key, + std::string const& range_end, + size_t const limit, int64_t revision) { + return Response::create( + this->ls_internal(key, range_end, limit, true, revision)); } -std::shared_ptr etcd::SyncClient::ls_internal(std::string const & key, size_t const limit, bool const keys_only, int64_t revision) { +std::shared_ptr etcd::SyncClient::ls_internal( + std::string const& key, size_t const limit, bool const keys_only, + int64_t revision) { etcdv3::ActionParameters params; params.key.assign(key); params.keys_only = keys_only; @@ -828,7 +863,9 @@ std::shared_ptr etcd::SyncClient::ls_internal(std::str return std::make_shared(std::move(params)); } -std::shared_ptr etcd::SyncClient::ls_internal(std::string const & key, std::string const &range_end, size_t const limit, bool const keys_only, int64_t revision) { +std::shared_ptr etcd::SyncClient::ls_internal( + std::string const& key, std::string const& range_end, size_t const limit, + bool const keys_only, int64_t revision) { etcdv3::ActionParameters params; params.key.assign(key); params.range_end.assign(range_end); @@ -842,17 +879,18 @@ std::shared_ptr etcd::SyncClient::ls_internal(std::str return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::watch(std::string const & key, bool recursive) -{ - return Response::create(this->watch_internal(key, 0 /* from current location */, recursive)); +etcd::Response etcd::SyncClient::watch(std::string const& key, bool recursive) { + return Response::create( + this->watch_internal(key, 0 /* from current location */, recursive)); } -etcd::Response etcd::SyncClient::watch(std::string const & key, int64_t fromIndex, bool recursive) -{ +etcd::Response etcd::SyncClient::watch(std::string const& key, + int64_t fromIndex, bool recursive) { return Response::create(this->watch_internal(key, fromIndex, recursive)); } -std::shared_ptr etcd::SyncClient::watch_internal(std::string const & key, int64_t fromIndex, bool recursive) { +std::shared_ptr etcd::SyncClient::watch_internal( + std::string const& key, int64_t fromIndex, bool recursive) { etcdv3::ActionParameters params; params.key.assign(key); params.withPrefix = recursive; @@ -863,22 +901,25 @@ std::shared_ptr etcd::SyncClient::watch_internal(std:: return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::watch(std::string const & key, const char *range_end) -{ +etcd::Response etcd::SyncClient::watch(std::string const& key, + const char* range_end) { return watch(key, std::string(range_end)); } -etcd::Response etcd::SyncClient::watch(std::string const & key, std::string const & range_end) -{ - return Response::create(this->watch_internal(key, range_end, 0 /* from current location */)); +etcd::Response etcd::SyncClient::watch(std::string const& key, + std::string const& range_end) { + return Response::create( + this->watch_internal(key, range_end, 0 /* from current location */)); } -etcd::Response etcd::SyncClient::watch(std::string const & key, std::string const & range_end, int64_t fromIndex) -{ +etcd::Response etcd::SyncClient::watch(std::string const& key, + std::string const& range_end, + int64_t fromIndex) { return Response::create(this->watch_internal(key, range_end, fromIndex)); } -std::shared_ptr etcd::SyncClient::watch_internal(std::string const & key, std::string const &range_end, int64_t fromIndex) { +std::shared_ptr etcd::SyncClient::watch_internal( + std::string const& key, std::string const& range_end, int64_t fromIndex) { etcdv3::ActionParameters params; params.key.assign(key); params.range_end.assign(range_end); @@ -890,8 +931,7 @@ std::shared_ptr etcd::SyncClient::watch_internal(std:: return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::leasegrant(int ttl) -{ +etcd::Response etcd::SyncClient::leasegrant(int ttl) { // lease grant is special, that we are expected the callback could be invoked // immediately after the lease is granted by the server. // @@ -917,25 +957,27 @@ std::shared_ptr etcd::SyncClient::leasekeepalive(int ttl) { // // - the wait-for-response starts immediately after the request been issued // - the keep alive thread starts immediately after the lease been granted - auto call = std::make_shared(std::move(params)); + auto call = + std::make_shared(std::move(params)); call->waitForResponse(); auto v3resp = call->ParseResponse(); - return std::make_shared(*this, ttl, v3resp.get_value().kvs.lease()); + return std::make_shared(*this, ttl, + v3resp.get_value().kvs.lease()); } -etcd::Response etcd::SyncClient::leaserevoke(int64_t lease_id) -{ +etcd::Response etcd::SyncClient::leaserevoke(int64_t lease_id) { return Response::create(this->leaserevoke_internal(lease_id)); } -std::shared_ptr etcd::SyncClient::leaserevoke_internal(int64_t lease_id) { +std::shared_ptr +etcd::SyncClient::leaserevoke_internal(int64_t lease_id) { etcdv3::ActionParameters params; params.lease_id = lease_id; params.auth_token.assign(this->token_authenticator->renew_if_expired()); // leaserevoke: no timeout // - // leaserevoke is special, as it calls `Finish()` inside the constructor, the timeout may - // trigger a "SIGABRT" error on Mac + // leaserevoke is special, as it calls `Finish()` inside the constructor, the + // timeout may trigger a "SIGABRT" error on Mac // // https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/runs/6544444692?check_suite_focus=true // @@ -944,26 +986,27 @@ std::shared_ptr etcd::SyncClient::leaserevoke_in return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::leasetimetolive(int64_t lease_id) -{ +etcd::Response etcd::SyncClient::leasetimetolive(int64_t lease_id) { return Response::create(this->leasetimetolive_internal(lease_id)); } -std::shared_ptr etcd::SyncClient::leasetimetolive_internal(int64_t lease_id) { +std::shared_ptr +etcd::SyncClient::leasetimetolive_internal(int64_t lease_id) { etcdv3::ActionParameters params; params.lease_id = lease_id; params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; params.lease_stub = stubs->leaseServiceStub.get(); - return std::make_shared(std::move(params)); + return std::make_shared( + std::move(params)); } -etcd::Response etcd::SyncClient::leases() -{ +etcd::Response etcd::SyncClient::leases() { return Response::create(this->leases_internal()); } -std::shared_ptr etcd::SyncClient::leases_internal() { +std::shared_ptr +etcd::SyncClient::leases_internal() { etcdv3::ActionParameters params; params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; @@ -971,7 +1014,7 @@ std::shared_ptr etcd::SyncClient::leases_interna return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::lock(std::string const &key) { +etcd::Response etcd::SyncClient::lock(std::string const& key) { // routines in lock usually will be fast, less than 10 seconds. // // (base on our experiences in vineyard and GraphScope). @@ -979,12 +1022,13 @@ etcd::Response etcd::SyncClient::lock(std::string const &key) { return this->lock(key, DEFAULT_LEASE_TTL_FOR_LOCK); } -etcd::Response etcd::SyncClient::lock(std::string const &key, int lease_ttl) { +etcd::Response etcd::SyncClient::lock(std::string const& key, int lease_ttl) { auto keepalive = this->leasekeepalive(lease_ttl); return this->lock_internal(key, keepalive); } -etcd::Response etcd::SyncClient::lock_internal(std::string const &key, std::shared_ptr const &keepalive) { +etcd::Response etcd::SyncClient::lock_internal( + std::string const& key, std::shared_ptr const& keepalive) { etcdv3::ActionParameters params; params.key = key; params.lease_id = keepalive->Lease(); @@ -1012,12 +1056,14 @@ etcd::Response etcd::SyncClient::lock_internal(std::string const &key, std::shar return lock_resp; } -etcd::Response etcd::SyncClient::lock_with_lease(std::string const &key, - int64_t lease_id) { +etcd::Response etcd::SyncClient::lock_with_lease(std::string const& key, + int64_t lease_id) { return Response::create(this->lock_with_lease_internal(key, lease_id)); } -std::shared_ptr etcd::SyncClient::lock_with_lease_internal(std::string const &key, int64_t lease_id) { +std::shared_ptr +etcd::SyncClient::lock_with_lease_internal(std::string const& key, + int64_t lease_id) { etcdv3::ActionParameters params; params.key = key; params.lease_id = lease_id; @@ -1027,11 +1073,12 @@ std::shared_ptr etcd::SyncClient::lock_with_lease_inter return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::unlock(std::string const &lock_key) { +etcd::Response etcd::SyncClient::unlock(std::string const& lock_key) { return Response::create(this->unlock_internal(lock_key)); } -std::shared_ptr etcd::SyncClient::unlock_internal(std::string const &lock_key) { +std::shared_ptr etcd::SyncClient::unlock_internal( + std::string const& lock_key) { etcdv3::ActionParameters params; params.key = lock_key; params.auth_token.assign(this->token_authenticator->renew_if_expired()); @@ -1071,11 +1118,12 @@ std::shared_ptr etcd::SyncClient::unlock_internal(std return call; } -etcd::Response etcd::SyncClient::txn(etcdv3::Transaction const &txn) { +etcd::Response etcd::SyncClient::txn(etcdv3::Transaction const& txn) { return Response::create(this->txn_internal(txn)); } -std::shared_ptr etcd::SyncClient::txn_internal(etcdv3::Transaction const &txn) { +std::shared_ptr etcd::SyncClient::txn_internal( + etcdv3::Transaction const& txn) { etcdv3::ActionParameters params; params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; @@ -1083,13 +1131,15 @@ std::shared_ptr etcd::SyncClient::txn_internal(etcdv3::T return std::make_shared(std::move(params), txn); } -etcd::Response etcd::SyncClient::campaign( - std::string const &name, int64_t lease_id, std::string const &value) { +etcd::Response etcd::SyncClient::campaign(std::string const& name, + int64_t lease_id, + std::string const& value) { return Response::create(this->campaign_internal(name, lease_id, value)); } -std::shared_ptr etcd::SyncClient::campaign_internal( - std::string const &name, int64_t lease_id, std::string const &value) { +std::shared_ptr +etcd::SyncClient::campaign_internal(std::string const& name, int64_t lease_id, + std::string const& value) { etcdv3::ActionParameters params; params.name = name; params.lease_id = lease_id; @@ -1100,15 +1150,19 @@ std::shared_ptr etcd::SyncClient::campaign_internal return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::proclaim( - std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value) { - return Response::create(this->proclaim_internal(name, lease_id, key, revision, value)); +etcd::Response etcd::SyncClient::proclaim(std::string const& name, + int64_t lease_id, + std::string const& key, + int64_t revision, + std::string const& value) { + return Response::create( + this->proclaim_internal(name, lease_id, key, revision, value)); } -std::shared_ptr etcd::SyncClient::proclaim_internal( - std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision, std::string const &value) { +std::shared_ptr +etcd::SyncClient::proclaim_internal(std::string const& name, int64_t lease_id, + std::string const& key, int64_t revision, + std::string const& value) { etcdv3::ActionParameters params; params.name = name; params.lease_id = lease_id; @@ -1121,11 +1175,12 @@ std::shared_ptr etcd::SyncClient::proclaim_internal return std::make_shared(std::move(params)); } -etcd::Response etcd::SyncClient::leader(std::string const &name) { +etcd::Response etcd::SyncClient::leader(std::string const& name) { return Response::create(this->leader_internal(name)); } -std::shared_ptr etcd::SyncClient::leader_internal(std::string const &name) { +std::shared_ptr etcd::SyncClient::leader_internal( + std::string const& name) { etcdv3::ActionParameters params; params.name = name; params.auth_token.assign(this->token_authenticator->renew_if_expired()); @@ -1135,24 +1190,28 @@ std::shared_ptr etcd::SyncClient::leader_internal(std } std::unique_ptr etcd::SyncClient::observe( - std::string const &name) { + std::string const& name) { etcdv3::ActionParameters params; params.name.assign(name); params.auth_token.assign(this->token_authenticator->renew_if_expired()); params.grpc_timeout = this->grpc_timeout; params.election_stub = stubs->electionServiceStub.get(); std::unique_ptr observer(new Observer()); - observer->action = std::make_shared(std::move(params)); + observer->action = + std::make_shared(std::move(params)); return observer; } -etcd::Response etcd::SyncClient::resign( - std::string const &name, int64_t lease_id, std::string const &key, int64_t revision) { +etcd::Response etcd::SyncClient::resign(std::string const& name, + int64_t lease_id, + std::string const& key, + int64_t revision) { return Response::create(this->resign_internal(name, lease_id, key, revision)); } -std::shared_ptr etcd::SyncClient::resign_internal(std::string const &name, int64_t lease_id, - std::string const &key, int64_t revision) { +std::shared_ptr etcd::SyncClient::resign_internal( + std::string const& name, int64_t lease_id, std::string const& key, + int64_t revision) { etcdv3::ActionParameters params; params.name = name; params.lease_id = lease_id; @@ -1164,7 +1223,7 @@ std::shared_ptr etcd::SyncClient::resign_internal(std return std::make_shared(std::move(params)); } -const std::string &etcd::SyncClient::current_auth_token() const { +const std::string& etcd::SyncClient::current_auth_token() const { return this->token_authenticator->renew_if_expired(); } diff --git a/src/Value.cpp b/src/Value.cpp index 809ac91..64bf1cd 100644 --- a/src/Value.cpp +++ b/src/Value.cpp @@ -4,18 +4,9 @@ #include "etcd/v3/KeyValue.hpp" etcd::Value::Value() - : dir(false), - created(0), - modified(0), - _version(0), - _ttl(0), - leaseId(0) -{ -} - + : dir(false), created(0), modified(0), _version(0), _ttl(0), leaseId(0) {} -etcd::Value::Value(etcdv3::KeyValue const & kv) -{ +etcd::Value::Value(etcdv3::KeyValue const& kv) { dir = false; _key = kv.kvs.key(); value = kv.kvs.value(); @@ -26,8 +17,7 @@ etcd::Value::Value(etcdv3::KeyValue const & kv) _ttl = kv.get_ttl(); } -etcd::Value::Value(mvccpb::KeyValue const & kv) -{ +etcd::Value::Value(mvccpb::KeyValue const& kv) { dir = false; _key = kv.key(); value = kv.value(); @@ -38,47 +28,23 @@ etcd::Value::Value(mvccpb::KeyValue const & kv) _ttl = -1; } -std::string const & etcd::Value::key() const -{ - return _key; -} +std::string const& etcd::Value::key() const { return _key; } -bool etcd::Value::is_dir() const -{ - return dir; -} +bool etcd::Value::is_dir() const { return dir; } -std::string const & etcd::Value::as_string() const -{ - return value; -} +std::string const& etcd::Value::as_string() const { return value; } -int64_t etcd::Value::created_index() const -{ - return created; -} +int64_t etcd::Value::created_index() const { return created; } -int64_t etcd::Value::modified_index() const -{ - return modified; -} +int64_t etcd::Value::modified_index() const { return modified; } -int64_t etcd::Value::version() const -{ - return _version; -} +int64_t etcd::Value::version() const { return _version; } -int etcd::Value::ttl() const -{ - return _ttl; -} +int etcd::Value::ttl() const { return _ttl; } -int64_t etcd::Value::lease() const -{ - return leaseId; -} +int64_t etcd::Value::lease() const { return leaseId; } -etcd::Event::Event(mvccpb::Event const & event) { +etcd::Event::Event(mvccpb::Event const& event) { _has_kv = event.has_kv(); _has_prev_kv = event.has_prev_kv(); if (_has_kv) { @@ -100,18 +66,10 @@ enum etcd::Event::EventType etcd::Event::event_type() const { return event_type_; } -bool etcd::Event::has_kv() const { - return _has_kv; -} +bool etcd::Event::has_kv() const { return _has_kv; } -bool etcd::Event::has_prev_kv() const { - return _has_prev_kv; -} +bool etcd::Event::has_prev_kv() const { return _has_prev_kv; } -const etcd::Value &etcd::Event::kv() const { - return _kv; -} +const etcd::Value& etcd::Event::kv() const { return _kv; } -const etcd::Value &etcd::Event::prev_kv() const { - return _prev_kv; -} +const etcd::Value& etcd::Event::prev_kv() const { return _prev_kv; } diff --git a/src/Watcher.cpp b/src/Watcher.cpp index c69ccf1..eacaa75 100644 --- a/src/Watcher.cpp +++ b/src/Watcher.cpp @@ -9,7 +9,8 @@ struct etcd::Watcher::EtcdServerStubs { std::unique_ptr call; }; -void etcd::Watcher::EtcdServerStubsDeleter::operator()(etcd::Watcher::EtcdServerStubs *stubs) { +void etcd::Watcher::EtcdServerStubsDeleter::operator()( + etcd::Watcher::EtcdServerStubs* stubs) { if (stubs) { if (stubs->watchServiceStub) { stubs->watchServiceStub.reset(); @@ -21,239 +22,205 @@ void etcd::Watcher::EtcdServerStubsDeleter::operator()(etcd::Watcher::EtcdServer } } -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, std::function callback, - std::function wait_callback, - bool recursive): - Watcher(client, key, -1, callback, wait_callback, recursive) { -} + std::function wait_callback, bool recursive) + : Watcher(client, key, -1, callback, wait_callback, recursive) {} -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, std::function callback, - std::function wait_callback): - Watcher(client, key, range_end, -1, callback, wait_callback) { -} + std::function wait_callback) + : Watcher(client, key, range_end, -1, callback, wait_callback) {} -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, int64_t fromIndex, +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + int64_t fromIndex, std::function callback, - std::function wait_callback, - bool recursive): - wait_callback(wait_callback), fromIndex(fromIndex), recursive(recursive) { + std::function wait_callback, bool recursive) + : wait_callback(wait_callback), fromIndex(fromIndex), recursive(recursive) { stubs.reset(new EtcdServerStubs{}); stubs->watchServiceStub = Watch::NewStub(client.channel); doWatch(key, "", client.current_auth_token(), callback); } -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, std::function callback, - std::function wait_callback): - wait_callback(wait_callback), fromIndex(fromIndex), recursive(false) { + std::function wait_callback) + : wait_callback(wait_callback), fromIndex(fromIndex), recursive(false) { stubs.reset(new EtcdServerStubs{}); stubs->watchServiceStub = Watch::NewStub(client.channel); doWatch(key, range_end, client.current_auth_token(), callback); } -etcd::Watcher::Watcher(std::string const & address, std::string const & key, +etcd::Watcher::Watcher(std::string const& address, std::string const& key, std::function callback, - std::function wait_callback, - bool recursive): - Watcher(address, key, -1, callback, wait_callback, recursive) { -} + std::function wait_callback, bool recursive) + : Watcher(address, key, -1, callback, wait_callback, recursive) {} -etcd::Watcher::Watcher(std::string const & address, std::string const & key, - std::string const & range_end, +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + std::string const& range_end, std::function callback, - std::function wait_callback): - Watcher(address, key, range_end, -1, callback, wait_callback) { -} + std::function wait_callback) + : Watcher(address, key, range_end, -1, callback, wait_callback) {} -etcd::Watcher::Watcher(std::string const & address, std::string const & key, int64_t fromIndex, +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + int64_t fromIndex, std::function callback, - std::function wait_callback, - bool recursive): - Watcher(SyncClient(address), key, fromIndex, callback, wait_callback, recursive) { -} + std::function wait_callback, bool recursive) + : Watcher(SyncClient(address), key, fromIndex, callback, wait_callback, + recursive) {} -etcd::Watcher::Watcher(std::string const & address, std::string const & key, - std::string const & range_end, int64_t fromIndex, +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + std::string const& range_end, int64_t fromIndex, std::function callback, - std::function wait_callback): - Watcher(SyncClient(address), key, range_end, fromIndex, callback, wait_callback) { -} + std::function wait_callback) + : Watcher(SyncClient(address), key, range_end, fromIndex, callback, + wait_callback) {} -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, std::function callback, - std::function wait_callback, - bool recursive, - int const auth_token_ttl): - Watcher(address, username, password, key, -1, callback, wait_callback, recursive, auth_token_ttl) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const & range_end, + std::function wait_callback, bool recursive, + int const auth_token_ttl) + : Watcher(address, username, password, key, -1, callback, wait_callback, + recursive, auth_token_ttl) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, std::function callback, std::function wait_callback, - int const auth_token_ttl): - Watcher(address, username, password, key, range_end, -1, callback, wait_callback, auth_token_ttl) { -} + int const auth_token_ttl) + : Watcher(address, username, password, key, range_end, -1, callback, + wait_callback, auth_token_ttl) {} -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, int64_t fromIndex, +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + int64_t fromIndex, std::function callback, - std::function wait_callback, - bool recursive, - int const auth_token_ttl): - Watcher(SyncClient(address, username, password, auth_token_ttl), key, fromIndex, callback, wait_callback, recursive) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const & range_end, int64_t fromIndex, + std::function wait_callback, bool recursive, + int const auth_token_ttl) + : Watcher(SyncClient(address, username, password, auth_token_ttl), key, + fromIndex, callback, wait_callback, recursive) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, int64_t fromIndex, std::function callback, std::function wait_callback, - int const auth_token_ttl): - Watcher(SyncClient(address, username, password, auth_token_ttl), key, range_end, fromIndex, callback, wait_callback) { -} + int const auth_token_ttl) + : Watcher(SyncClient(address, username, password, auth_token_ttl), key, + range_end, fromIndex, callback, wait_callback) {} -etcd::Watcher::Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, int64_t fromIndex, +etcd::Watcher::Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, int64_t fromIndex, std::function callback, - std::function wait_callback, - bool recursive, - std::string const & target_name_override): - Watcher(SyncClient(address, ca, cert, privkey, target_name_override), key, fromIndex, callback, wait_callback, recursive) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, std::string const & range_end, int64_t fromIndex, + std::function wait_callback, bool recursive, + std::string const& target_name_override) + : Watcher(SyncClient(address, ca, cert, privkey, target_name_override), key, + fromIndex, callback, wait_callback, recursive) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, std::string const& range_end, + int64_t fromIndex, std::function callback, std::function wait_callback, - std::string const & target_name_override): - Watcher(SyncClient(address, ca, cert, privkey, target_name_override), key, range_end, fromIndex, callback, wait_callback) { -} - -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, - std::function callback, - bool recursive): - Watcher(client, key, callback, nullptr, recursive) { -} - -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, - std::function callback): - Watcher(client, key, range_end, callback, nullptr) { -} - -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive): - Watcher(client, key, fromIndex, callback, nullptr, recursive) { -} - -etcd::Watcher::Watcher(SyncClient const &client, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback): - Watcher(client, key, range_end, fromIndex, callback, nullptr) { -} - -etcd::Watcher::Watcher(std::string const & address, std::string const & key, + std::string const& target_name_override) + : Watcher(SyncClient(address, ca, cert, privkey, target_name_override), key, + range_end, fromIndex, callback, wait_callback) {} + +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + std::function callback, bool recursive) + : Watcher(client, key, callback, nullptr, recursive) {} + +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, + std::function callback) + : Watcher(client, key, range_end, callback, nullptr) {} + +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + int64_t fromIndex, + std::function callback, bool recursive) + : Watcher(client, key, fromIndex, callback, nullptr, recursive) {} + +etcd::Watcher::Watcher(SyncClient const& client, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback) + : Watcher(client, key, range_end, fromIndex, callback, nullptr) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + std::function callback, bool recursive) + : Watcher(address, key, callback, nullptr, recursive) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + std::string const& range_end, + std::function callback) + : Watcher(address, key, range_end, callback, nullptr) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + int64_t fromIndex, + std::function callback, bool recursive) + : Watcher(address, key, fromIndex, callback, nullptr, recursive) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& key, + std::string const& range_end, int64_t fromIndex, + std::function callback) + : Watcher(address, key, range_end, fromIndex, callback, nullptr) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::function callback, bool recursive, + int const auth_token_ttl) + : Watcher(address, username, password, key, callback, nullptr, recursive, + auth_token_ttl) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, std::function callback, - bool recursive): - Watcher(address, key, callback, nullptr, recursive) { -} - -etcd::Watcher::Watcher(std::string const & address, std::string const & key, - std::string const &range_end, - std::function callback): - Watcher(address, key, range_end, callback, nullptr) { -} - -etcd::Watcher::Watcher(std::string const & address, std::string const & key, int64_t fromIndex, + int const auth_token_ttl) + : Watcher(address, username, password, key, range_end, callback, nullptr, + auth_token_ttl) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + int64_t fromIndex, + std::function callback, bool recursive, + int const auth_token_ttl) + : Watcher(address, username, password, key, fromIndex, callback, nullptr, + recursive, auth_token_ttl) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& username, + std::string const& password, std::string const& key, + std::string const& range_end, int64_t fromIndex, std::function callback, - bool recursive): - Watcher(address, key, fromIndex, callback, nullptr, recursive) { -} - -etcd::Watcher::Watcher(std::string const & address, std::string const & key, - std::string const &range_end, int64_t fromIndex, - std::function callback): - Watcher(address, key, range_end, fromIndex, callback, nullptr) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, + int const auth_token_ttl) + : Watcher(address, username, password, key, range_end, fromIndex, callback, + nullptr, auth_token_ttl) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, int64_t fromIndex, + std::function callback, bool recursive, + std::string const& target_name_override) + : Watcher(address, ca, cert, privkey, key, fromIndex, callback, nullptr, + recursive, target_name_override) {} + +etcd::Watcher::Watcher(std::string const& address, std::string const& ca, + std::string const& cert, std::string const& privkey, + std::string const& key, std::string const& range_end, + int64_t fromIndex, std::function callback, - bool recursive, - int const auth_token_ttl): - Watcher(address, username, password, key, callback, nullptr, recursive, auth_token_ttl) { -} + std::string const& target_name_override) + : Watcher(address, ca, cert, privkey, key, range_end, fromIndex, callback, + nullptr, target_name_override) {} -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, - std::function callback, - int const auth_token_ttl): - Watcher(address, username, password, key, range_end, callback, nullptr, auth_token_ttl) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive, - int const auth_token_ttl): - Watcher(address, username, password, key, fromIndex, callback, nullptr, recursive, auth_token_ttl) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & username, std::string const & password, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - int const auth_token_ttl): - Watcher(address, username, password, key, range_end, fromIndex, callback, nullptr, auth_token_ttl) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, int64_t fromIndex, - std::function callback, - bool recursive, - std::string const & target_name_override): - Watcher(address, ca, cert, privkey, key, fromIndex, callback, nullptr, recursive, target_name_override) { -} - -etcd::Watcher::Watcher(std::string const & address, - std::string const & ca, - std::string const & cert, - std::string const & privkey, - std::string const & key, std::string const &range_end, int64_t fromIndex, - std::function callback, - std::string const & target_name_override): - Watcher(address, ca, cert, privkey, key, range_end, fromIndex, callback, nullptr, target_name_override) { -} - -etcd::Watcher::~Watcher() -{ - this->Cancel(); -} +etcd::Watcher::~Watcher() { this->Cancel(); } -bool etcd::Watcher::Wait() -{ +bool etcd::Watcher::Wait() { if (!cancelled.exchange(true)) { if (task_.joinable()) { task_.join(); @@ -262,31 +229,29 @@ bool etcd::Watcher::Wait() return stubs->call->Cancelled(); } -void etcd::Watcher::Wait(std::function callback) -{ +void etcd::Watcher::Wait(std::function callback) { if (wait_callback == nullptr) { wait_callback = callback; } else { - std::cerr << "Failed to set a asynchronous wait callback since it has already been set" << std::endl; + std::cerr << "Failed to set a asynchronous wait callback since it has " + "already been set" + << std::endl; } } -bool etcd::Watcher::Cancel() -{ +bool etcd::Watcher::Cancel() { stubs->call->CancelWatch(); return this->Wait(); } -bool etcd::Watcher::Cancelled() const -{ +bool etcd::Watcher::Cancelled() const { return cancelled.load() || stubs->call->Cancelled(); } -void etcd::Watcher::doWatch(std::string const & key, - std::string const & range_end, - std::string const & auth_token, - std::function callback) -{ +void etcd::Watcher::doWatch(std::string const& key, + std::string const& range_end, + std::string const& auth_token, + std::function callback) { etcdv3::ActionParameters params; params.auth_token.assign(auth_token); // n.b.: watch: no need for timeout @@ -304,13 +269,12 @@ void etcd::Watcher::doWatch(std::string const & key, stubs->call->waitForResponse(callback); if (wait_callback != nullptr) { // issue the callback in another thread (detached) to avoid deadlock, - // it is ok to detach a pplx::task, but we don't want to use the pplx::task - // in the core library + // it is ok to detach a pplx::task, but we don't want to use the + // pplx::task in the core library bool cancelled = stubs->call->Cancelled(); std::function wait_callback = this->wait_callback; - std::thread canceller([wait_callback, cancelled]() { - wait_callback(cancelled); - }); + std::thread canceller( + [wait_callback, cancelled]() { wait_callback(cancelled); }); canceller.detach(); } }); diff --git a/src/v3/Action.cpp b/src/v3/Action.cpp index 4c8c857..fff45e4 100644 --- a/src/v3/Action.cpp +++ b/src/v3/Action.cpp @@ -1,16 +1,14 @@ +#include "etcd/v3/Action.hpp" #include #include #include "etcd/v3/action_constants.hpp" -#include "etcd/v3/Action.hpp" -etcdv3::Action::Action(etcdv3::ActionParameters const ¶ms) -{ +etcdv3::Action::Action(etcdv3::ActionParameters const& params) { parameters = params; this->InitAction(); } -etcdv3::Action::Action(etcdv3::ActionParameters && params) -{ +etcdv3::Action::Action(etcdv3::ActionParameters&& params) { parameters = std::move(params); this->InitAction(); } @@ -32,8 +30,7 @@ void etcdv3::Action::InitAction() { start_timepoint = std::chrono::high_resolution_clock::now(); } -etcdv3::ActionParameters::ActionParameters() -{ +etcdv3::ActionParameters::ActionParameters() { withPrefix = false; revision = 0; old_revision = 0; @@ -50,11 +47,12 @@ bool etcdv3::ActionParameters::has_grpc_timeout() const { return this->grpc_timeout != std::chrono::microseconds::zero(); } -std::chrono::system_clock::time_point etcdv3::ActionParameters::grpc_deadline() const { +std::chrono::system_clock::time_point etcdv3::ActionParameters::grpc_deadline() + const { return std::chrono::system_clock::now() + this->grpc_timeout; } -void etcdv3::ActionParameters::dump(std::ostream &os) const { +void etcdv3::ActionParameters::dump(std::ostream& os) const { os << "ActionParameters:" << std::endl; os << " withPrefix: " << withPrefix << std::endl; os << " revision: " << revision << std::endl; @@ -73,39 +71,43 @@ void etcdv3::ActionParameters::dump(std::ostream &os) const { os << " grpc_timeout: " << grpc_timeout.count() << "(ms)" << std::endl; } -void etcdv3::Action::waitForResponse() -{ +void etcdv3::Action::waitForResponse() { void* got_tag; bool ok = false; if (parameters.has_grpc_timeout()) { switch (cq_.AsyncNext(&got_tag, &ok, parameters.grpc_deadline())) { - case CompletionQueue::NextStatus::TIMEOUT: { - status = grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, "gRPC timeout"); - break; - } - case CompletionQueue::NextStatus::SHUTDOWN: { - status = grpc::Status(grpc::StatusCode::UNAVAILABLE, "gRPC already shutdown"); - break; - } - case CompletionQueue::NextStatus::GOT_EVENT: { - if (!ok) { - status = grpc::Status(grpc::StatusCode::ABORTED, "Failed to execute the action: not ok or invalid tag"); - } - break; + case CompletionQueue::NextStatus::TIMEOUT: { + status = + grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, "gRPC timeout"); + break; + } + case CompletionQueue::NextStatus::SHUTDOWN: { + status = + grpc::Status(grpc::StatusCode::UNAVAILABLE, "gRPC already shutdown"); + break; + } + case CompletionQueue::NextStatus::GOT_EVENT: { + if (!ok) { + status = + grpc::Status(grpc::StatusCode::ABORTED, + "Failed to execute the action: not ok or invalid tag"); } + break; + } } } else { cq_.Next(&got_tag, &ok); - GPR_ASSERT(got_tag == (void*)this); + GPR_ASSERT(got_tag == (void*) this); } } -const std::chrono::high_resolution_clock::time_point etcdv3::Action::startTimepoint() { +const std::chrono::high_resolution_clock::time_point +etcdv3::Action::startTimepoint() { return this->start_timepoint; } -std::string etcdv3::detail::string_plus_one(std::string const &value) { +std::string etcdv3::detail::string_plus_one(std::string const& value) { // Referred from the Go implementation in etcd. for (int32_t i = value.size() - 1; i >= 0; --i) { if (static_cast(value[i]) < 0xff) { @@ -117,7 +119,8 @@ std::string etcdv3::detail::string_plus_one(std::string const &value) { return {etcdv3::NUL}; } -std::string etcdv3::detail::resolve_etcd_endpoints(std::string const&default_endpoints) { - const char *ep = std::getenv("ETCD_ENDPOINTS"); +std::string etcdv3::detail::resolve_etcd_endpoints( + std::string const& default_endpoints) { + const char* ep = std::getenv("ETCD_ENDPOINTS"); return ep ? ep : default_endpoints; } diff --git a/src/v3/AsyncGRPC.cpp b/src/v3/AsyncGRPC.cpp index 30115d2..bd900db 100644 --- a/src/v3/AsyncGRPC.cpp +++ b/src/v3/AsyncGRPC.cpp @@ -4,81 +4,62 @@ #include -#include "etcd/v3/action_constants.hpp" -#include "etcd/v3/Transaction.hpp" #include "etcd/Response.hpp" +#include "etcd/v3/Transaction.hpp" +#include "etcd/v3/action_constants.hpp" -using etcdserverpb::RangeRequest; +using etcdserverpb::DeleteRangeRequest; +using etcdserverpb::LeaseCheckpointRequest; +using etcdserverpb::LeaseGrantRequest; +using etcdserverpb::LeaseKeepAliveRequest; +using etcdserverpb::LeaseLeasesRequest; +using etcdserverpb::LeaseRevokeRequest; +using etcdserverpb::LeaseTimeToLiveRequest; using etcdserverpb::PutRequest; -using etcdserverpb::RequestOp; -using etcdserverpb::ResponseOp; -using etcdserverpb::TxnRequest; using etcdserverpb::RangeRequest; -using etcdserverpb::PutRequest; using etcdserverpb::RequestOp; using etcdserverpb::ResponseOp; using etcdserverpb::TxnRequest; -using etcdserverpb::DeleteRangeRequest; -using v3electionpb::LeaderKey; +using etcdserverpb::WatchCreateRequest; using v3electionpb::CampaignRequest; using v3electionpb::CampaignResponse; -using v3electionpb::ProclaimRequest; -using v3electionpb::ProclaimResponse; +using v3electionpb::LeaderKey; using v3electionpb::LeaderRequest; using v3electionpb::LeaderResponse; +using v3electionpb::ProclaimRequest; +using v3electionpb::ProclaimResponse; using v3electionpb::ResignRequest; using v3electionpb::ResignResponse; -using etcdserverpb::ResponseOp; -using etcdserverpb::RangeRequest; -using etcdserverpb::LeaseGrantRequest; -using etcdserverpb::LeaseRevokeRequest; -using etcdserverpb::LeaseCheckpointRequest; -using etcdserverpb::LeaseKeepAliveRequest; -using etcdserverpb::LeaseTimeToLiveRequest; -using etcdserverpb::LeaseLeasesRequest; using v3lockpb::LockRequest; using v3lockpb::UnlockRequest; -using etcdserverpb::PutRequest; -using etcdserverpb::RangeRequest; -using etcdserverpb::ResponseOp; -using etcdserverpb::RangeRequest; -using etcdserverpb::PutRequest; -using etcdserverpb::RequestOp; -using etcdserverpb::ResponseOp; -using etcdserverpb::TxnRequest; -using etcdserverpb::WatchCreateRequest; void etcdv3::AsyncCampaignResponse::ParseResponse(CampaignResponse& reply) { index = reply.header().revision(); - auto const &leader = reply.leader(); + auto const& leader = reply.leader(); name = leader.name(); value.kvs.set_key(leader.key()); value.kvs.set_create_revision(leader.rev()); value.kvs.set_lease(leader.lease()); } -void etcdv3::AsyncDeleteResponse::ParseResponse(std::string const& key, bool prefix, DeleteRangeResponse& resp) -{ +void etcdv3::AsyncDeleteResponse::ParseResponse(std::string const& key, + bool prefix, + DeleteRangeResponse& resp) { index = resp.header().revision(); - if(resp.prev_kvs_size() == 0) - { + if (resp.prev_kvs_size() == 0) { error_code = etcdv3::ERROR_KEY_NOT_FOUND; error_message = "etcd-cpp-apiv3: key not found"; - } - else - { - //get all previous values - for(int cnt=0; cnt < resp.prev_kvs_size(); cnt++) - { + } else { + // get all previous values + for (int cnt = 0; cnt < resp.prev_kvs_size(); cnt++) { etcdv3::KeyValue kv; kv.kvs.CopyFrom(resp.prev_kvs(cnt)); values.push_back(kv); } - if(!prefix) - { + if (!prefix) { prev_value = values[0]; value = values[0]; value.kvs.clear_value(); @@ -87,8 +68,7 @@ void etcdv3::AsyncDeleteResponse::ParseResponse(std::string const& key, bool pre } } -void etcdv3::AsyncHeadResponse::ParseResponse(RangeResponse& resp) -{ +void etcdv3::AsyncHeadResponse::ParseResponse(RangeResponse& resp) { cluster_id = resp.header().cluster_id(); member_id = resp.header().member_id(); index = resp.header().revision(); @@ -108,32 +88,35 @@ void etcdv3::AsyncLeaseGrantResponse::ParseResponse(LeaseGrantResponse& resp) { error_message = resp.error(); } -void etcdv3::AsyncLeaseKeepAliveResponse::ParseResponse(LeaseKeepAliveResponse& resp) { +void etcdv3::AsyncLeaseKeepAliveResponse::ParseResponse( + LeaseKeepAliveResponse& resp) { index = resp.header().revision(); value.kvs.set_lease(resp.id()); value.set_ttl(resp.ttl()); } -void etcdv3::AsyncLeaseLeasesResponse::ParseResponse(LeaseLeasesResponse& resp) { +void etcdv3::AsyncLeaseLeasesResponse::ParseResponse( + LeaseLeasesResponse& resp) { index = resp.header().revision(); for (auto lease : resp.leases()) { leases.emplace_back(lease.id()); } } -void etcdv3::AsyncLeaseRevokeResponse::ParseResponse(LeaseRevokeResponse& resp) { +void etcdv3::AsyncLeaseRevokeResponse::ParseResponse( + LeaseRevokeResponse& resp) { index = resp.header().revision(); } -void etcdv3::AsyncLeaseTimeToLiveResponse::ParseResponse(LeaseTimeToLiveResponse& resp) { +void etcdv3::AsyncLeaseTimeToLiveResponse::ParseResponse( + LeaseTimeToLiveResponse& resp) { index = resp.header().revision(); value.kvs.set_lease(resp.id()); value.set_ttl(resp.ttl()); // FIXME: unsupported: fields "grantedTTL" and "keys" } -void etcdv3::AsyncLockResponse::ParseResponse(LockResponse& resp) -{ +void etcdv3::AsyncLockResponse::ParseResponse(LockResponse& resp) { index = resp.header().revision(); lock_key = resp.key(); } @@ -148,36 +131,30 @@ void etcdv3::AsyncProclaimResponse::ParseResponse(ProclaimResponse& reply) { index = reply.header().revision(); } -void etcdv3::AsyncPutResponse::ParseResponse(PutResponse& resp) -{ +void etcdv3::AsyncPutResponse::ParseResponse(PutResponse& resp) { index = resp.header().revision(); - //get all previous values + // get all previous values etcdv3::KeyValue kv; kv.kvs.CopyFrom(resp.prev_kv()); prev_value = kv; } -void etcdv3::AsyncRangeResponse::ParseResponse(RangeResponse& resp, bool prefix) -{ +void etcdv3::AsyncRangeResponse::ParseResponse(RangeResponse& resp, + bool prefix) { index = resp.header().revision(); - if(resp.kvs_size() == 0 && !prefix) - { + if (resp.kvs_size() == 0 && !prefix) { error_code = etcdv3::ERROR_KEY_NOT_FOUND; error_message = "etcd-cpp-apiv3: key not found"; return; - } - else - { - for(int index=0; index < resp.kvs_size(); index++) - { + } else { + for (int index = 0; index < resp.kvs_size(); index++) { etcdv3::KeyValue kv; kv.kvs.CopyFrom(resp.kvs(index)); values.push_back(kv); } - if(!prefix) - { + if (!prefix) { value = values[0]; values.clear(); } @@ -192,35 +169,30 @@ void etcdv3::AsyncTxnResponse::ParseResponse(TxnResponse& reply) { index = reply.header().revision(); } -void etcdv3::AsyncTxnResponse::ParseResponse(std::string const& key, bool prefix, TxnResponse& reply) -{ +void etcdv3::AsyncTxnResponse::ParseResponse(std::string const& key, + bool prefix, TxnResponse& reply) { index = reply.header().revision(); - for(int index=0; index < reply.responses_size(); index++) - { + for (int index = 0; index < reply.responses_size(); index++) { auto resp = reply.responses(index); - if(ResponseOp::ResponseCase::kResponseRange == resp.response_case()) - { + if (ResponseOp::ResponseCase::kResponseRange == resp.response_case()) { AsyncRangeResponse response; - response.ParseResponse(*(resp.mutable_response_range()),prefix); + response.ParseResponse(*(resp.mutable_response_range()), prefix); error_code = response.get_error_code(); error_message = response.get_error_message(); values = response.get_values(); value = response.get_value(); - } - else if(ResponseOp::ResponseCase::kResponsePut == resp.response_case()) - { + } else if (ResponseOp::ResponseCase::kResponsePut == resp.response_case()) { auto put_resp = resp.response_put(); - if(put_resp.has_prev_kv()) - { + if (put_resp.has_prev_kv()) { prev_value.kvs.CopyFrom(put_resp.prev_kv()); } - } - else if(ResponseOp::ResponseCase::kResponseDeleteRange == resp.response_case()) - { + } else if (ResponseOp::ResponseCase::kResponseDeleteRange == + resp.response_case()) { AsyncDeleteResponse response; - response.ParseResponse(key,prefix,*(resp.mutable_response_delete_range())); + response.ParseResponse(key, prefix, + *(resp.mutable_response_delete_range())); prev_value.kvs.CopyFrom(response.get_prev_value().kvs); @@ -230,13 +202,11 @@ void etcdv3::AsyncTxnResponse::ParseResponse(std::string const& key, bool prefix } } -void etcdv3::AsyncUnlockResponse::ParseResponse(UnlockResponse& resp) -{ +void etcdv3::AsyncUnlockResponse::ParseResponse(UnlockResponse& resp) { index = resp.header().revision(); } -void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) -{ +void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) { if (reply.canceled() && reply.compact_revision() != 0) { error_code = grpc::StatusCode::OUT_OF_RANGE; error_message = "required revision has been compacted"; @@ -244,31 +214,24 @@ void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) return; } index = reply.header().revision(); - for (auto const &e: reply.events()) { + for (auto const& e : reply.events()) { events.emplace_back(e); } - for(int cnt =0; cnt < reply.events_size(); cnt++) - { + for (int cnt = 0; cnt < reply.events_size(); cnt++) { auto event = reply.events(cnt); - if(mvccpb::Event::EventType::Event_EventType_PUT == event.type()) - { - if(event.kv().version() == 1) - { + if (mvccpb::Event::EventType::Event_EventType_PUT == event.type()) { + if (event.kv().version() == 1) { action = etcdv3::CREATE_ACTION; - } - else - { + } else { action = etcdv3::SET_ACTION; } value.kvs = event.kv(); - } - else if(mvccpb::Event::EventType::Event_EventType_DELETE_ == event.type()) - { + } else if (mvccpb::Event::EventType::Event_EventType_DELETE_ == + event.type()) { action = etcdv3::DELETE_ACTION; value.kvs = event.kv(); } - if(event.has_prev_kv()) - { + if (event.has_prev_kv()) { prev_value.kvs = event.prev_kv(); } // just store the first occurence of the key in values. @@ -279,74 +242,62 @@ void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) } etcdv3::AsyncCampaignAction::AsyncCampaignAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { CampaignRequest campaign_request; campaign_request.set_name(parameters.name); campaign_request.set_lease(parameters.lease_id); campaign_request.set_value(parameters.value); - response_reader = parameters.election_stub->AsyncCampaign(&context, campaign_request, &cq_); - response_reader->Finish(&reply, &status, (void *)this); + response_reader = + parameters.election_stub->AsyncCampaign(&context, campaign_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncCampaignResponse etcdv3::AsyncCampaignAction::ParseResponse() -{ +etcdv3::AsyncCampaignResponse etcdv3::AsyncCampaignAction::ParseResponse() { AsyncCampaignResponse campaign_resp; campaign_resp.set_action(etcdv3::CAMPAIGN_ACTION); - if(!status.ok()) { + if (!status.ok()) { campaign_resp.set_error_code(status.error_code()); campaign_resp.set_error_message(status.error_message()); - } - else { + } else { campaign_resp.ParseResponse(reply); } return campaign_resp; } etcdv3::AsyncCompareAndDeleteAction::AsyncCompareAndDeleteAction( - etcdv3::ActionParameters && params, etcdv3::AtomicityType type) - :etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params, etcdv3::AtomicityType type) + : etcdv3::Action(std::move(params)) { etcdv3::Transaction transaction(parameters.key); - if(type == etcdv3::AtomicityType::PREV_VALUE) - { - transaction.init_compare(parameters.old_value, - CompareResult::EQUAL, + if (type == etcdv3::AtomicityType::PREV_VALUE) { + transaction.init_compare(parameters.old_value, CompareResult::EQUAL, CompareTarget::VALUE); - } - else if (type == etcdv3::AtomicityType::PREV_INDEX) - { - transaction.init_compare(parameters.old_revision, - CompareResult::EQUAL, + } else if (type == etcdv3::AtomicityType::PREV_INDEX) { + transaction.init_compare(parameters.old_revision, CompareResult::EQUAL, CompareTarget::MOD); } transaction.setup_compare_and_delete_operation(parameters.key); transaction.setup_basic_failure_operation(parameters.key); - response_reader = parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse() -{ +etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse() { AsyncTxnResponse txn_resp; txn_resp.set_action(etcdv3::COMPAREDELETE_ACTION); - if(!status.ok()) - { + if (!status.ok()) { txn_resp.set_error_code(status.error_code()); txn_resp.set_error_message(status.error_message()); - } - else - { + } else { txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); - if(!reply.succeeded()) - { + if (!reply.succeeded()) { txn_resp.set_error_code(ERROR_COMPARE_FAILED); txn_resp.set_error_message("etcd-cpp-apiv3: compare failed"); } @@ -356,48 +307,39 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndDeleteAction::ParseResponse() } etcdv3::AsyncCompareAndSwapAction::AsyncCompareAndSwapAction( - etcdv3::ActionParameters && params, etcdv3::AtomicityType type) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params, etcdv3::AtomicityType type) + : etcdv3::Action(std::move(params)) { etcdv3::Transaction transaction(parameters.key); - if(type == etcdv3::AtomicityType::PREV_VALUE) - { - transaction.init_compare(parameters.old_value, - CompareResult::EQUAL, + if (type == etcdv3::AtomicityType::PREV_VALUE) { + transaction.init_compare(parameters.old_value, CompareResult::EQUAL, CompareTarget::VALUE); - } - else if (type == etcdv3::AtomicityType::PREV_INDEX) - { - transaction.init_compare(parameters.old_revision, - CompareResult::EQUAL, + } else if (type == etcdv3::AtomicityType::PREV_INDEX) { + transaction.init_compare(parameters.old_revision, CompareResult::EQUAL, CompareTarget::MOD); } transaction.setup_basic_failure_operation(parameters.key); - transaction.setup_compare_and_swap_sequence(parameters.value, parameters.lease_id); + transaction.setup_compare_and_swap_sequence(parameters.value, + parameters.lease_id); - response_reader = parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse() -{ +etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse() { AsyncTxnResponse txn_resp; txn_resp.set_action(etcdv3::COMPARESWAP_ACTION); - if(!status.ok()) - { + if (!status.ok()) { txn_resp.set_error_code(status.error_code()); txn_resp.set_error_message(status.error_message()); - } - else - { + } else { txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); - //if there is an error code returned by parseResponse, we must - //not overwrite it. - if(!reply.succeeded() && !txn_resp.get_error_code()) - { + // if there is an error code returned by parseResponse, we must + // not overwrite it. + if (!reply.succeeded() && !txn_resp.get_error_code()) { txn_resp.set_error_code(ERROR_COMPARE_FAILED); txn_resp.set_error_message("etcd-cpp-apiv3: compare failed"); } @@ -406,10 +348,8 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncCompareAndSwapAction::ParseResponse() return txn_resp; } -etcdv3::AsyncDeleteAction::AsyncDeleteAction( - ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncDeleteAction::AsyncDeleteAction(ActionParameters&& params) + : etcdv3::Action(std::move(params)) { DeleteRangeRequest del_request; if (!parameters.withPrefix) { del_request.set_key(parameters.key); @@ -423,103 +363,92 @@ etcdv3::AsyncDeleteAction::AsyncDeleteAction( del_request.set_range_end(detail::string_plus_one(parameters.key)); } } - if(!parameters.range_end.empty()) { + if (!parameters.range_end.empty()) { del_request.set_range_end(parameters.range_end); } del_request.set_prev_kv(true); - response_reader = parameters.kv_stub->AsyncDeleteRange(&context, del_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.kv_stub->AsyncDeleteRange(&context, del_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncDeleteResponse etcdv3::AsyncDeleteAction::ParseResponse() -{ +etcdv3::AsyncDeleteResponse etcdv3::AsyncDeleteAction::ParseResponse() { AsyncDeleteResponse del_resp; del_resp.set_action(etcdv3::DELETE_ACTION); - if(!status.ok()) - { + if (!status.ok()) { del_resp.set_error_code(status.error_code()); del_resp.set_error_message(status.error_message()); - } - else - { - del_resp.ParseResponse(parameters.key, parameters.withPrefix || !parameters.range_end.empty(), reply); + } else { + del_resp.ParseResponse( + parameters.key, parameters.withPrefix || !parameters.range_end.empty(), + reply); } return del_resp; } -etcdv3::AsyncHeadAction::AsyncHeadAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncHeadAction::AsyncHeadAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { RangeRequest get_request; get_request.set_key(etcdv3::NUL); get_request.set_limit(1); - response_reader = parameters.kv_stub->AsyncRange(&context,get_request,&cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.kv_stub->AsyncRange(&context, get_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncHeadResponse etcdv3::AsyncHeadAction::ParseResponse() -{ +etcdv3::AsyncHeadResponse etcdv3::AsyncHeadAction::ParseResponse() { AsyncHeadResponse head_resp; head_resp.set_action(etcdv3::GET_ACTION); - if(!status.ok()) - { + if (!status.ok()) { head_resp.set_error_code(status.error_code()); head_resp.set_error_message(status.error_message()); - } - else - { + } else { head_resp.ParseResponse(reply); } return head_resp; } -etcdv3::AsyncLeaderAction::AsyncLeaderAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncLeaderAction::AsyncLeaderAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaderRequest leader_request; leader_request.set_name(parameters.name); - response_reader = parameters.election_stub->AsyncLeader(&context, leader_request, &cq_); - response_reader->Finish(&reply, &status, (void *)this); + response_reader = + parameters.election_stub->AsyncLeader(&context, leader_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLeaderResponse etcdv3::AsyncLeaderAction::ParseResponse() -{ +etcdv3::AsyncLeaderResponse etcdv3::AsyncLeaderAction::ParseResponse() { AsyncLeaderResponse leader_resp; leader_resp.set_action(etcdv3::LEADER_ACTION); - if(!status.ok()) { + if (!status.ok()) { leader_resp.set_error_code(status.error_code()); leader_resp.set_error_message(status.error_message()); - } - else { + } else { leader_resp.ParseResponse(reply); } return leader_resp; } etcdv3::AsyncLeaseGrantAction::AsyncLeaseGrantAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaseGrantRequest leasegrant_request; leasegrant_request.set_ttl(parameters.ttl); // If ID is set to 0, etcd will choose an ID. leasegrant_request.set_id(parameters.lease_id); - response_reader = parameters.lease_stub->AsyncLeaseGrant(&context, leasegrant_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.lease_stub->AsyncLeaseGrant( + &context, leasegrant_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse() -{ +etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse() { AsyncLeaseGrantResponse lease_resp; lease_resp.set_action(etcdv3::LEASEGRANT); @@ -533,23 +462,24 @@ etcdv3::AsyncLeaseGrantResponse etcdv3::AsyncLeaseGrantAction::ParseResponse() } etcdv3::AsyncLeaseKeepAliveAction::AsyncLeaseKeepAliveAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { isCancelled = false; - stream = parameters.lease_stub->AsyncLeaseKeepAlive(&context, &cq_, (void*)etcdv3::KEEPALIVE_CREATE); + stream = parameters.lease_stub->AsyncLeaseKeepAlive( + &context, &cq_, (void*) etcdv3::KEEPALIVE_CREATE); - void *got_tag = nullptr; + void* got_tag = nullptr; bool ok = false; - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::KEEPALIVE_CREATE) { + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::KEEPALIVE_CREATE) { // ok } else { throw std::runtime_error("Failed to create a lease keep-alive connection"); } } -etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::ParseResponse() -{ +etcdv3::AsyncLeaseKeepAliveResponse +etcdv3::AsyncLeaseKeepAliveAction::ParseResponse() { AsyncLeaseKeepAliveResponse lease_resp; lease_resp.set_action(etcdv3::LEASEKEEPALIVE); @@ -562,105 +492,119 @@ etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::ParseResp return lease_resp; } -etcd::Response etcdv3::AsyncLeaseKeepAliveAction::Refresh() -{ +etcd::Response etcdv3::AsyncLeaseKeepAliveAction::Refresh() { std::lock_guard scope_lock(this->protect_is_cancelled); auto start_timepoint = std::chrono::high_resolution_clock::now(); if (isCancelled) { status = grpc::Status::CANCELLED; - return etcd::Response(ParseResponse(), etcd::detail::duration_till_now(start_timepoint)); + return etcd::Response(ParseResponse(), + etcd::detail::duration_till_now(start_timepoint)); } LeaseKeepAliveRequest leasekeepalive_request; leasekeepalive_request.set_id(parameters.lease_id); - void *got_tag = nullptr; + void* got_tag = nullptr; bool ok = false; if (parameters.has_grpc_timeout()) { - stream->Write(leasekeepalive_request, (void *)etcdv3::KEEPALIVE_WRITE); + stream->Write(leasekeepalive_request, (void*) etcdv3::KEEPALIVE_WRITE); // wait write finish switch (cq_.AsyncNext(&got_tag, &ok, parameters.grpc_deadline())) { - case CompletionQueue::NextStatus::TIMEOUT: { - status = grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, "gRPC timeout during keep alive write"); - break; - } - case CompletionQueue::NextStatus::SHUTDOWN: { - status = grpc::Status(grpc::StatusCode::UNAVAILABLE, "gRPC already shutdown during keep alive write"); - break; - } - case CompletionQueue::NextStatus::GOT_EVENT: { - if (!ok || got_tag != (void *)etcdv3::KEEPALIVE_WRITE) { - return etcd::Response(grpc::StatusCode::ABORTED, "Failed to create a lease keep-alive connection: write not ok or invalid tag"); - } + case CompletionQueue::NextStatus::TIMEOUT: { + status = grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, + "gRPC timeout during keep alive write"); + break; + } + case CompletionQueue::NextStatus::SHUTDOWN: { + status = grpc::Status(grpc::StatusCode::UNAVAILABLE, + "gRPC already shutdown during keep alive write"); + break; + } + case CompletionQueue::NextStatus::GOT_EVENT: { + if (!ok || got_tag != (void*) etcdv3::KEEPALIVE_WRITE) { + return etcd::Response(grpc::StatusCode::ABORTED, + "Failed to create a lease keep-alive connection: " + "write not ok or invalid tag"); } } + } if (!status.ok()) { this->CancelKeepAlive(); - return etcd::Response(ParseResponse(), etcd::detail::duration_till_now(start_timepoint)); + return etcd::Response(ParseResponse(), + etcd::detail::duration_till_now(start_timepoint)); } - stream->Read(&reply, (void*)etcdv3::KEEPALIVE_READ); + stream->Read(&reply, (void*) etcdv3::KEEPALIVE_READ); // wait read finish switch (cq_.AsyncNext(&got_tag, &ok, parameters.grpc_deadline())) { - case CompletionQueue::NextStatus::TIMEOUT: { - status = grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, "gRPC timeout during keep alive read"); - break; - } - case CompletionQueue::NextStatus::SHUTDOWN: { - status = grpc::Status(grpc::StatusCode::UNAVAILABLE, "gRPC already shutdown during keep alive read"); - break; - } - case CompletionQueue::NextStatus::GOT_EVENT: { - if (ok && got_tag == (void *)etcdv3::KEEPALIVE_READ) { - return etcd::Response(ParseResponse(), etcd::detail::duration_till_now(start_timepoint)); - } - break; + case CompletionQueue::NextStatus::TIMEOUT: { + status = grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, + "gRPC timeout during keep alive read"); + break; + } + case CompletionQueue::NextStatus::SHUTDOWN: { + status = grpc::Status(grpc::StatusCode::UNAVAILABLE, + "gRPC already shutdown during keep alive read"); + break; + } + case CompletionQueue::NextStatus::GOT_EVENT: { + if (ok && got_tag == (void*) etcdv3::KEEPALIVE_READ) { + return etcd::Response(ParseResponse(), + etcd::detail::duration_till_now(start_timepoint)); } + break; + } } this->CancelKeepAlive(); - return etcd::Response(grpc::StatusCode::ABORTED, "Failed to create a lease keep-alive connection: read not ok or invalid tag"); + return etcd::Response(grpc::StatusCode::ABORTED, + "Failed to create a lease keep-alive connection: " + "read not ok or invalid tag"); } else { - stream->Write(leasekeepalive_request, (void *)etcdv3::KEEPALIVE_WRITE); + stream->Write(leasekeepalive_request, (void*) etcdv3::KEEPALIVE_WRITE); // wait write finish - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::KEEPALIVE_WRITE) { - stream->Read(&reply, (void*)etcdv3::KEEPALIVE_READ); + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::KEEPALIVE_WRITE) { + stream->Read(&reply, (void*) etcdv3::KEEPALIVE_READ); // wait read finish - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::KEEPALIVE_READ) { - return etcd::Response(ParseResponse(), etcd::detail::duration_till_now(start_timepoint)); + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::KEEPALIVE_READ) { + return etcd::Response(ParseResponse(), + etcd::detail::duration_till_now(start_timepoint)); } } this->CancelKeepAlive(); - return etcd::Response(grpc::StatusCode::ABORTED, "Failed to create a lease keep-alive connection: read not ok or invalid tag"); + return etcd::Response(grpc::StatusCode::ABORTED, + "Failed to create a lease keep-alive connection: " + "read not ok or invalid tag"); } } -void etcdv3::AsyncLeaseKeepAliveAction::CancelKeepAlive() -{ +void etcdv3::AsyncLeaseKeepAliveAction::CancelKeepAlive() { std::lock_guard scope_lock(this->protect_is_cancelled); - if(isCancelled == false) - { + if (isCancelled == false) { isCancelled = true; - void *got_tag = nullptr; + void* got_tag = nullptr; bool ok = false; - stream->WritesDone((void*)etcdv3::KEEPALIVE_DONE); - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::KEEPALIVE_DONE) { + stream->WritesDone((void*) etcdv3::KEEPALIVE_DONE); + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::KEEPALIVE_DONE) { // ok } else { std::cerr << "Failed to mark a lease keep-alive connection as DONE: " << context.debug_error_string() << std::endl; } - stream->Finish(&status, (void *)KEEPALIVE_FINISH); - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)KEEPALIVE_FINISH) { + stream->Finish(&status, (void*) KEEPALIVE_FINISH); + if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void*) KEEPALIVE_FINISH) { // ok } else { std::cerr << "Failed to finish a lease keep-alive connection: " - << status.error_message() - << ", " << context.debug_error_string() << std::endl; + << status.error_message() << ", " + << context.debug_error_string() << std::endl; } // cancel on-the-fly calls @@ -670,27 +614,27 @@ void etcdv3::AsyncLeaseKeepAliveAction::CancelKeepAlive() } } -bool etcdv3::AsyncLeaseKeepAliveAction::Cancelled() const -{ +bool etcdv3::AsyncLeaseKeepAliveAction::Cancelled() const { return isCancelled; } -etcdv3::ActionParameters& etcdv3::AsyncLeaseKeepAliveAction::mutable_parameters() { +etcdv3::ActionParameters& +etcdv3::AsyncLeaseKeepAliveAction::mutable_parameters() { return this->parameters; } etcdv3::AsyncLeaseLeasesAction::AsyncLeaseLeasesAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaseLeasesRequest leaseleases_request; - response_reader = parameters.lease_stub->AsyncLeaseLeases(&context, leaseleases_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.lease_stub->AsyncLeaseLeases( + &context, leaseleases_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLeaseLeasesResponse etcdv3::AsyncLeaseLeasesAction::ParseResponse() -{ +etcdv3::AsyncLeaseLeasesResponse +etcdv3::AsyncLeaseLeasesAction::ParseResponse() { AsyncLeaseLeasesResponse lease_resp; lease_resp.set_action(etcdv3::LEASELEASES); @@ -704,18 +648,18 @@ etcdv3::AsyncLeaseLeasesResponse etcdv3::AsyncLeaseLeasesAction::ParseResponse() } etcdv3::AsyncLeaseRevokeAction::AsyncLeaseRevokeAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaseRevokeRequest leaserevoke_request; leaserevoke_request.set_id(parameters.lease_id); - response_reader = parameters.lease_stub->AsyncLeaseRevoke(&context, leaserevoke_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.lease_stub->AsyncLeaseRevoke( + &context, leaserevoke_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLeaseRevokeResponse etcdv3::AsyncLeaseRevokeAction::ParseResponse() -{ +etcdv3::AsyncLeaseRevokeResponse +etcdv3::AsyncLeaseRevokeAction::ParseResponse() { AsyncLeaseRevokeResponse lease_resp; lease_resp.set_action(etcdv3::LEASEREVOKE); @@ -729,20 +673,20 @@ etcdv3::AsyncLeaseRevokeResponse etcdv3::AsyncLeaseRevokeAction::ParseResponse() } etcdv3::AsyncLeaseTimeToLiveAction::AsyncLeaseTimeToLiveAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaseTimeToLiveRequest leasetimetolive_request; leasetimetolive_request.set_id(parameters.lease_id); // FIXME: unsupported parameters: "keys" // leasetimetolive_request.set_keys(parameters.keys); - response_reader = parameters.lease_stub->AsyncLeaseTimeToLive(&context, leasetimetolive_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.lease_stub->AsyncLeaseTimeToLive( + &context, leasetimetolive_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLeaseTimeToLiveResponse etcdv3::AsyncLeaseTimeToLiveAction::ParseResponse() -{ +etcdv3::AsyncLeaseTimeToLiveResponse +etcdv3::AsyncLeaseTimeToLiveAction::ParseResponse() { AsyncLeaseTimeToLiveResponse lease_resp; lease_resp.set_action(etcdv3::LEASETIMETOLIVE); @@ -755,55 +699,51 @@ etcdv3::AsyncLeaseTimeToLiveResponse etcdv3::AsyncLeaseTimeToLiveAction::ParseRe return lease_resp; } -etcdv3::AsyncLockAction::AsyncLockAction( - ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncLockAction::AsyncLockAction(ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LockRequest lock_request; lock_request.set_name(parameters.key); lock_request.set_lease(parameters.lease_id); - response_reader = parameters.lock_stub->AsyncLock(&context, lock_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.lock_stub->AsyncLock(&context, lock_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncLockResponse etcdv3::AsyncLockAction::ParseResponse() -{ +etcdv3::AsyncLockResponse etcdv3::AsyncLockAction::ParseResponse() { AsyncLockResponse lock_resp; lock_resp.set_action(etcdv3::LOCK_ACTION); - if(!status.ok()) - { + if (!status.ok()) { lock_resp.set_error_code(status.error_code()); lock_resp.set_error_message(status.error_message()); - } - else - { + } else { lock_resp.ParseResponse(reply); } return lock_resp; } -etcdv3::AsyncObserveAction::AsyncObserveAction(etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncObserveAction::AsyncObserveAction( + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { LeaderRequest leader_request; leader_request.set_name(parameters.name); - response_reader = parameters.election_stub->AsyncObserve(&context, leader_request, &cq_, (void *)etcdv3::ELECTION_OBSERVE_CREATE); + response_reader = parameters.election_stub->AsyncObserve( + &context, leader_request, &cq_, (void*) etcdv3::ELECTION_OBSERVE_CREATE); - void *got_tag; + void* got_tag; bool ok = false; - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::ELECTION_OBSERVE_CREATE) { + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::ELECTION_OBSERVE_CREATE) { // n.b.: leave the issue of `Read` to the `waitForResponse` } else { throw std::runtime_error("failed to create a observe connection"); } } -void etcdv3::AsyncObserveAction::waitForResponse() -{ +void etcdv3::AsyncObserveAction::waitForResponse() { void* got_tag; bool ok = false; @@ -814,8 +754,8 @@ void etcdv3::AsyncObserveAction::waitForResponse() return; } - response_reader->Read(&reply, (void *)this); - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void*)this) { + response_reader->Read(&reply, (void*) this); + if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void*) this) { auto response = ParseResponse(); if (response.get_error_code() != 0) { this->CancelObserve(); @@ -826,26 +766,28 @@ void etcdv3::AsyncObserveAction::waitForResponse() } } -void etcdv3::AsyncObserveAction::CancelObserve() -{ +void etcdv3::AsyncObserveAction::CancelObserve() { std::lock_guard scope_lock(this->protect_is_cancalled); if (!isCancelled.exchange(true)) { void* got_tag; bool ok = false; - response_reader->Finish(&status, (void *)ELECTION_OBSERVE_FINISH); + response_reader->Finish(&status, (void*) ELECTION_OBSERVE_FINISH); // FIXME: not sure why the `Next()` after `Finish()` blocks forever. // Using the `AsyncNext()` without a timeout to ensure the cancel is done. - switch (cq_.AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::microseconds(1))) { - case CompletionQueue::NextStatus::TIMEOUT: - case CompletionQueue::NextStatus::SHUTDOWN: - // ignore - break; - case CompletionQueue::NextStatus::GOT_EVENT: - if (!ok || got_tag != (void *)ELECTION_OBSERVE_FINISH) { - std::cerr << "Failed to finish a election observing connection" << std::endl; - } + switch (cq_.AsyncNext( + &got_tag, &ok, + std::chrono::system_clock::now() + std::chrono::microseconds(1))) { + case CompletionQueue::NextStatus::TIMEOUT: + case CompletionQueue::NextStatus::SHUTDOWN: + // ignore + break; + case CompletionQueue::NextStatus::GOT_EVENT: + if (!ok || got_tag != (void*) ELECTION_OBSERVE_FINISH) { + std::cerr << "Failed to finish a election observing connection" + << std::endl; + } } // cancel on-the-fly calls @@ -859,25 +801,22 @@ bool etcdv3::AsyncObserveAction::Cancelled() const { return isCancelled.load(); } -etcdv3::AsyncObserveResponse etcdv3::AsyncObserveAction::ParseResponse() -{ +etcdv3::AsyncObserveResponse etcdv3::AsyncObserveAction::ParseResponse() { AsyncObserveResponse leader_resp; leader_resp.set_action(etcdv3::OBSERVE_ACTION); - if(!status.ok()) { + if (!status.ok()) { leader_resp.set_error_code(status.error_code()); leader_resp.set_error_message(status.error_message()); - } - else { + } else { leader_resp.ParseResponse(reply); } return leader_resp; } etcdv3::AsyncProclaimAction::AsyncProclaimAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ + etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { auto leader = new LeaderKey(); leader->set_name(parameters.name); leader->set_key(parameters.key); @@ -888,29 +827,26 @@ etcdv3::AsyncProclaimAction::AsyncProclaimAction( proclaim_request.set_allocated_leader(leader); proclaim_request.set_value(parameters.value); - response_reader = parameters.election_stub->AsyncProclaim(&context, proclaim_request, &cq_); - response_reader->Finish(&reply, &status, (void *)this); + response_reader = + parameters.election_stub->AsyncProclaim(&context, proclaim_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncProclaimResponse etcdv3::AsyncProclaimAction::ParseResponse() -{ +etcdv3::AsyncProclaimResponse etcdv3::AsyncProclaimAction::ParseResponse() { AsyncProclaimResponse proclaim_resp; proclaim_resp.set_action(etcdv3::PROCLAIM_ACTION); - if(!status.ok()) { + if (!status.ok()) { proclaim_resp.set_error_code(status.error_code()); proclaim_resp.set_error_message(status.error_message()); - } - else { + } else { proclaim_resp.ParseResponse(reply); } return proclaim_resp; } -etcdv3::AsyncPutAction::AsyncPutAction( - ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncPutAction::AsyncPutAction(ActionParameters&& params) + : etcdv3::Action(std::move(params)) { PutRequest put_request; put_request.set_key(parameters.key); put_request.set_value(parameters.value); @@ -918,31 +854,25 @@ etcdv3::AsyncPutAction::AsyncPutAction( put_request.set_prev_kv(true); response_reader = parameters.kv_stub->AsyncPut(&context, put_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncPutResponse etcdv3::AsyncPutAction::ParseResponse() -{ +etcdv3::AsyncPutResponse etcdv3::AsyncPutAction::ParseResponse() { AsyncPutResponse put_resp; put_resp.set_action(etcdv3::PUT_ACTION); - if(!status.ok()) - { + if (!status.ok()) { put_resp.set_error_code(status.error_code()); put_resp.set_error_message(status.error_message()); - } - else - { + } else { put_resp.ParseResponse(reply); } - return put_resp; + return put_resp; } -etcdv3::AsyncRangeAction::AsyncRangeAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncRangeAction::AsyncRangeAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { RangeRequest get_request; if (!parameters.withPrefix) { get_request.set_key(parameters.key); @@ -956,45 +886,41 @@ etcdv3::AsyncRangeAction::AsyncRangeAction( get_request.set_range_end(detail::string_plus_one(parameters.key)); } } - if(!parameters.range_end.empty()) { + if (!parameters.range_end.empty()) { get_request.set_range_end(parameters.range_end); } - if(parameters.revision > 0) { + if (parameters.revision > 0) { get_request.set_revision(parameters.revision); } get_request.set_limit(parameters.limit); - get_request.set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_NONE); + get_request.set_sort_order( + RangeRequest::SortOrder::RangeRequest_SortOrder_NONE); // set keys_only and count_only get_request.set_keys_only(params.keys_only); get_request.set_count_only(params.count_only); - response_reader = parameters.kv_stub->AsyncRange(&context,get_request,&cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = parameters.kv_stub->AsyncRange(&context, get_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncRangeResponse etcdv3::AsyncRangeAction::ParseResponse() -{ +etcdv3::AsyncRangeResponse etcdv3::AsyncRangeAction::ParseResponse() { AsyncRangeResponse range_resp; range_resp.set_action(etcdv3::GET_ACTION); - if(!status.ok()) - { + if (!status.ok()) { range_resp.set_error_code(status.error_code()); range_resp.set_error_message(status.error_message()); - } - else - { - range_resp.ParseResponse(reply, parameters.withPrefix || !parameters.range_end.empty()); + } else { + range_resp.ParseResponse( + reply, parameters.withPrefix || !parameters.range_end.empty()); } return range_resp; } -etcdv3::AsyncResignAction::AsyncResignAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncResignAction::AsyncResignAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { auto leader = new LeaderKey(); leader->set_name(parameters.name); leader->set_key(parameters.key); @@ -1004,65 +930,56 @@ etcdv3::AsyncResignAction::AsyncResignAction( ResignRequest resign_request; resign_request.set_allocated_leader(leader); - response_reader = parameters.election_stub->AsyncResign(&context, resign_request, &cq_); - response_reader->Finish(&reply, &status, (void *)this); + response_reader = + parameters.election_stub->AsyncResign(&context, resign_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncResignResponse etcdv3::AsyncResignAction::ParseResponse() -{ +etcdv3::AsyncResignResponse etcdv3::AsyncResignAction::ParseResponse() { AsyncResignResponse resign_resp; resign_resp.set_action(etcdv3::RESIGN_ACTION); - if(!status.ok()) { + if (!status.ok()) { resign_resp.set_error_code(status.error_code()); resign_resp.set_error_message(status.error_message()); - } - else { + } else { resign_resp.ParseResponse(reply); } return resign_resp; } -etcdv3::AsyncSetAction::AsyncSetAction( - etcdv3::ActionParameters && params, bool create) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncSetAction::AsyncSetAction(etcdv3::ActionParameters&& params, + bool create) + : etcdv3::Action(std::move(params)) { etcdv3::Transaction transaction(parameters.key); isCreate = create; - transaction.init_compare(CompareResult::EQUAL, - CompareTarget::VERSION); + transaction.init_compare(CompareResult::EQUAL, CompareTarget::VERSION); - transaction.setup_basic_create_sequence(parameters.key, parameters.value, parameters.lease_id); + transaction.setup_basic_create_sequence(parameters.key, parameters.value, + parameters.lease_id); - if(isCreate) - { + if (isCreate) { transaction.setup_basic_failure_operation(parameters.key); + } else { + transaction.setup_set_failure_operation(parameters.key, parameters.value, + parameters.lease_id); } - else - { - transaction.setup_set_failure_operation(parameters.key, parameters.value, parameters.lease_id); - } - response_reader = parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncTxnResponse etcdv3::AsyncSetAction::ParseResponse() -{ - +etcdv3::AsyncTxnResponse etcdv3::AsyncSetAction::ParseResponse() { AsyncTxnResponse txn_resp; - txn_resp.set_action(isCreate? etcdv3::CREATE_ACTION : etcdv3::SET_ACTION); + txn_resp.set_action(isCreate ? etcdv3::CREATE_ACTION : etcdv3::SET_ACTION); - if(!status.ok()) - { + if (!status.ok()) { txn_resp.set_error_code(status.error_code()); txn_resp.set_error_message(status.error_message()); - } - else - { + } else { txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); - if(!reply.succeeded() && isCreate) - { + if (!reply.succeeded() && isCreate) { txn_resp.set_error_code(etcdv3::ERROR_KEY_ALREADY_EXISTS); txn_resp.set_error_message("etcd-cpp-apiv3: key already exists"); } @@ -1070,32 +987,27 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncSetAction::ParseResponse() return txn_resp; } -etcdv3::AsyncTxnAction::AsyncTxnAction( - etcdv3::ActionParameters && params, etcdv3::Transaction const &tx) - : etcdv3::Action(std::move(params)) -{ - response_reader = parameters.kv_stub->AsyncTxn(&context, *tx.txn_request, &cq_); - response_reader->Finish(&reply, &status, (void *)this); +etcdv3::AsyncTxnAction::AsyncTxnAction(etcdv3::ActionParameters&& params, + etcdv3::Transaction const& tx) + : etcdv3::Action(std::move(params)) { + response_reader = + parameters.kv_stub->AsyncTxn(&context, *tx.txn_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse() -{ +etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse() { AsyncTxnResponse txn_resp; txn_resp.set_action(etcdv3::TXN_ACTION); - if(!status.ok()) - { + if (!status.ok()) { txn_resp.set_error_code(status.error_code()); txn_resp.set_error_message(status.error_message()); - } - else - { + } else { txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); - //if there is an error code returned by parseResponse, we must - //not overwrite it. - if(!reply.succeeded() && !txn_resp.get_error_code()) - { + // if there is an error code returned by parseResponse, we must + // not overwrite it. + if (!reply.succeeded() && !txn_resp.get_error_code()) { txn_resp.set_error_code(ERROR_COMPARE_FAILED); txn_resp.set_error_message("etcd-cpp-apiv3: compare failed"); } @@ -1104,67 +1016,54 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncTxnAction::ParseResponse() return txn_resp; } -etcdv3::AsyncUnlockAction::AsyncUnlockAction( - ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncUnlockAction::AsyncUnlockAction(ActionParameters&& params) + : etcdv3::Action(std::move(params)) { UnlockRequest unlock_request; unlock_request.set_key(parameters.key); - response_reader = parameters.lock_stub->AsyncUnlock(&context, unlock_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.lock_stub->AsyncUnlock(&context, unlock_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncUnlockResponse etcdv3::AsyncUnlockAction::ParseResponse() -{ +etcdv3::AsyncUnlockResponse etcdv3::AsyncUnlockAction::ParseResponse() { AsyncUnlockResponse unlock_resp; unlock_resp.set_action(etcdv3::UNLOCK_ACTION); - if(!status.ok()) - { + if (!status.ok()) { unlock_resp.set_error_code(status.error_code()); unlock_resp.set_error_message(status.error_message()); - } - else - { + } else { unlock_resp.ParseResponse(reply); } return unlock_resp; } -etcdv3::AsyncUpdateAction::AsyncUpdateAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncUpdateAction::AsyncUpdateAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { etcdv3::Transaction transaction(parameters.key); - transaction.init_compare(CompareResult::GREATER, - CompareTarget::VERSION); + transaction.init_compare(CompareResult::GREATER, CompareTarget::VERSION); - transaction.setup_compare_and_swap_sequence(parameters.value, parameters.lease_id); + transaction.setup_compare_and_swap_sequence(parameters.value, + parameters.lease_id); - response_reader = parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); - response_reader->Finish(&reply, &status, (void*)this); + response_reader = + parameters.kv_stub->AsyncTxn(&context, *transaction.txn_request, &cq_); + response_reader->Finish(&reply, &status, (void*) this); } -etcdv3::AsyncTxnResponse etcdv3::AsyncUpdateAction::ParseResponse() -{ +etcdv3::AsyncTxnResponse etcdv3::AsyncUpdateAction::ParseResponse() { AsyncTxnResponse txn_resp; - if(!status.ok()) - { + if (!status.ok()) { txn_resp.set_error_code(status.error_code()); txn_resp.set_error_message(status.error_message()); - } - else - { - if(reply.succeeded()) - { + } else { + if (reply.succeeded()) { txn_resp.ParseResponse(parameters.key, parameters.withPrefix, reply); txn_resp.set_action(etcdv3::UPDATE_ACTION); - } - else - { + } else { txn_resp.set_error_code(etcdv3::ERROR_KEY_NOT_FOUND); txn_resp.set_error_message("etcd-cpp-apiv3: key not found"); } @@ -1172,18 +1071,21 @@ etcdv3::AsyncTxnResponse etcdv3::AsyncUpdateAction::ParseResponse() return txn_resp; } -etcdv3::AsyncWatchAction::AsyncWatchAction( - etcdv3::ActionParameters && params) - : etcdv3::Action(std::move(params)) -{ +etcdv3::AsyncWatchAction::AsyncWatchAction(etcdv3::ActionParameters&& params) + : etcdv3::Action(std::move(params)) { isCancelled.store(false); - stream = parameters.watch_stub->AsyncWatch(&context,&cq_,(void*)etcdv3::WATCH_CREATE); - this->watch_id = std::chrono::steady_clock::now().time_since_epoch().count(); + stream = parameters.watch_stub->AsyncWatch(&context, &cq_, + (void*) etcdv3::WATCH_CREATE); + this->watch_id = + std::chrono::high_resolution_clock::now().time_since_epoch().count(); +#ifndef NDEBUG + std::clog << "etcd-cpp-apiv3: watch_id: " << this->watch_id << std::endl; +#endif WatchRequest watch_req; WatchCreateRequest watch_create_req; - if(!parameters.withPrefix) { + if (!parameters.withPrefix) { watch_create_req.set_key(parameters.key); } else { if (parameters.key.empty()) { @@ -1194,7 +1096,7 @@ etcdv3::AsyncWatchAction::AsyncWatchAction( watch_create_req.set_range_end(detail::string_plus_one(parameters.key)); } } - if(!parameters.range_end.empty()) { + if (!parameters.range_end.empty()) { watch_create_req.set_range_end(parameters.range_end); } @@ -1205,69 +1107,67 @@ etcdv3::AsyncWatchAction::AsyncWatchAction( watch_req.mutable_create_request()->CopyFrom(watch_create_req); // wait "create" success (the stream becomes ready) - void *got_tag; + void* got_tag; bool ok = false; - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::WATCH_CREATE) { - stream->Write(watch_req, (void *)etcdv3::WATCH_WRITE); + if (cq_.Next(&got_tag, &ok) && ok && + got_tag == (void*) etcdv3::WATCH_CREATE) { + stream->Write(watch_req, (void*) etcdv3::WATCH_WRITE); } else { throw std::runtime_error("failed to create a watch connection"); } - // wait "write" (WatchCreateRequest) success, and start to read the first reply - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)etcdv3::WATCH_WRITE) { - stream->Read(&reply, (void*)this); - this->watch_id = reply.watch_id(); + // wait "write" (WatchCreateRequest) success, and start to read the first + // reply + if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void*) etcdv3::WATCH_WRITE) { + stream->Read(&reply, (void*) this); } else { throw std::runtime_error("failed to write WatchCreateRequest to server"); } } -void etcdv3::AsyncWatchAction::waitForResponse() -{ +void etcdv3::AsyncWatchAction::waitForResponse() { void* got_tag; bool ok = false; - while(cq_.Next(&got_tag, &ok)) - { - if(ok == false) - { + while (cq_.Next(&got_tag, &ok)) { + if (ok == false) { break; } - if(got_tag == (void *)etcdv3::WATCH_WRITE_CANCEL) { - stream->WritesDone((void*)etcdv3::WATCH_WRITES_DONE); + if (got_tag == (void*) etcdv3::WATCH_WRITE_CANCEL) { + stream->WritesDone((void*) etcdv3::WATCH_WRITES_DONE); continue; } - if(got_tag == (void*)etcdv3::WATCH_WRITES_DONE) - { - stream->Finish(&status, (void *)etcdv3::WATCH_FINISH); + if (got_tag == (void*) etcdv3::WATCH_WRITES_DONE) { + stream->Finish(&status, (void*) etcdv3::WATCH_FINISH); continue; } - if (got_tag == (void *)etcdv3::WATCH_FINISH) { + if (got_tag == (void*) etcdv3::WATCH_FINISH) { // shutdown cq_.Shutdown(); break; } - if(got_tag == (void*)this) // read tag + if (got_tag == (void*) this) // read tag { if (reply.canceled()) { - // cancel on-the-fly calls, but don't shutdown the completion queue as there - // are still a inflight call to finish + // cancel on-the-fly calls, but don't shutdown the completion queue as + // there are still a inflight call to finish context.TryCancel(); continue; } - // record the watcher id - this->watch_id = reply.watch_id(); - // we stop watch under two conditions: // - // 1. watch for a future revision, return immediately with empty events set + // 1. watch for a future revision, return immediately with empty events + // set // 2. receive any effective events. - if ((reply.created() && reply.header().revision() < parameters.revision) || + if ((reply.created() && + reply.header().revision() < parameters.revision) || reply.events_size() > 0) { // leave a warning if the response is too large and been fragmented if (reply.fragment()) { - std::cerr << "WARN: The response hasn't been fully received and parsed" << std::endl; + std::cerr + << "WARN: The response hasn't been fully received and parsed" + << std::endl; } std::cout << "issue a watch cancel" << std::endl; @@ -1276,60 +1176,54 @@ void etcdv3::AsyncWatchAction::waitForResponse() // start the next round to read finish messages, read into "&dummy" // (use nullptr, as it won't be touched). - stream->Read(nullptr, (void*)etcdv3::WATCH_FINISH); + stream->Read(nullptr, (void*) etcdv3::WATCH_FINISH); } else { // start the next round to read reply, read into "&reply" - stream->Read(&reply, (void*)this); + stream->Read(&reply, (void*) this); } continue; } - if(isCancelled.load()) { + if (isCancelled.load()) { // invalid tag, and is cancelled break; } } } -void etcdv3::AsyncWatchAction::CancelWatch() -{ +void etcdv3::AsyncWatchAction::CancelWatch() { if (!isCancelled.exchange(true)) { WatchRequest cancel_req; cancel_req.mutable_cancel_request()->set_watch_id(this->watch_id); - stream->Write(cancel_req, (void *)etcdv3::WATCH_WRITE_CANCEL); + stream->Write(cancel_req, (void*) etcdv3::WATCH_WRITE_CANCEL); isCancelled.store(true); } } -bool etcdv3::AsyncWatchAction::Cancelled() const { - return isCancelled.load(); -} +bool etcdv3::AsyncWatchAction::Cancelled() const { return isCancelled.load(); } -void etcdv3::AsyncWatchAction::waitForResponse(std::function callback) -{ +void etcdv3::AsyncWatchAction::waitForResponse( + std::function callback) { void* got_tag; bool ok = false; - while(cq_.Next(&got_tag, &ok)) - { - if(ok == false) - { + while (cq_.Next(&got_tag, &ok)) { + if (ok == false) { break; } - if(got_tag == (void *)etcdv3::WATCH_WRITE_CANCEL) { - stream->WritesDone((void*)etcdv3::WATCH_WRITES_DONE); + if (got_tag == (void*) etcdv3::WATCH_WRITE_CANCEL) { + stream->WritesDone((void*) etcdv3::WATCH_WRITES_DONE); continue; } - if(got_tag == (void*)etcdv3::WATCH_WRITES_DONE) - { - stream->Finish(&status, (void *)etcdv3::WATCH_FINISH); + if (got_tag == (void*) etcdv3::WATCH_WRITES_DONE) { + stream->Finish(&status, (void*) etcdv3::WATCH_FINISH); continue; } - if (got_tag == (void *)etcdv3::WATCH_FINISH) { + if (got_tag == (void*) etcdv3::WATCH_FINISH) { // shutdown cq_.Shutdown(); break; } - if(got_tag == (void*)this) // read tag + if (got_tag == (void*) this) // read tag { if (reply.canceled()) { if (reply.compact_revision() != 0) { @@ -1338,48 +1232,40 @@ void etcdv3::AsyncWatchAction::waitForResponse(std::functionwatch_id = reply.watch_id(); - // for the callback case, we don't invoke callback immediately if watching // for a future revision, we wait until there are some effective events. - if(reply.events_size()) - { + if (reply.events_size()) { auto resp = ParseResponse(); auto duration = std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - start_timepoint); callback(etcd::Response(resp, duration)); start_timepoint = std::chrono::high_resolution_clock::now(); } - stream->Read(&reply, (void*)this); + stream->Read(&reply, (void*) this); continue; } - if(isCancelled.load()) { + if (isCancelled.load()) { // invalid tag, and is cancelled break; } } } -etcdv3::AsyncWatchResponse etcdv3::AsyncWatchAction::ParseResponse() -{ +etcdv3::AsyncWatchResponse etcdv3::AsyncWatchAction::ParseResponse() { AsyncWatchResponse watch_resp; watch_resp.set_action(etcdv3::WATCH_ACTION); watch_resp.set_watch_id(reply.watch_id()); - if(!status.ok()) - { + if (!status.ok()) { watch_resp.set_error_code(status.error_code()); watch_resp.set_error_message(status.error_message()); - } - else - { + } else { watch_resp.ParseResponse(reply); } return watch_resp; diff --git a/src/v3/KeyValue.cpp b/src/v3/KeyValue.cpp index d3ab6d9..786dd5a 100644 --- a/src/v3/KeyValue.cpp +++ b/src/v3/KeyValue.cpp @@ -1,16 +1,7 @@ #include "etcd/v3/KeyValue.hpp" -etcdv3::KeyValue::KeyValue() -{ - ttl = 0; -} +etcdv3::KeyValue::KeyValue() { ttl = 0; } -void etcdv3::KeyValue::set_ttl(int ttl) -{ - this->ttl = ttl; -} +void etcdv3::KeyValue::set_ttl(int ttl) { this->ttl = ttl; } -int etcdv3::KeyValue::get_ttl() const -{ - return ttl; -} +int etcdv3::KeyValue::get_ttl() const { return ttl; } diff --git a/src/v3/Transaction.cpp b/src/v3/Transaction.cpp index f12557d..98f86f9 100644 --- a/src/v3/Transaction.cpp +++ b/src/v3/Transaction.cpp @@ -3,199 +3,210 @@ #include "proto/rpc.grpc.pb.h" using etcdserverpb::Compare; -using etcdserverpb::RangeRequest; +using etcdserverpb::DeleteRangeRequest; using etcdserverpb::PutRequest; +using etcdserverpb::RangeRequest; using etcdserverpb::RequestOp; -using etcdserverpb::DeleteRangeRequest; namespace etcdv3 { namespace detail { static etcdserverpb::Compare::CompareResult to_compare_result(CompareResult r) { - return static_cast(static_cast(r)); + return static_cast(static_cast(r)); } static etcdserverpb::Compare::CompareTarget to_compare_target(CompareTarget t) { - return static_cast(static_cast(t)); + return static_cast(static_cast(t)); } -} +} // namespace detail -} +} // namespace etcdv3 etcdv3::Transaction::Transaction() { - txn_request.reset(new etcdserverpb::TxnRequest{}); + txn_request.reset(new etcdserverpb::TxnRequest{}); } etcdv3::Transaction::Transaction(const std::string& key) : key(key) { - txn_request.reset(new etcdserverpb::TxnRequest{}); + txn_request.reset(new etcdserverpb::TxnRequest{}); } -void etcdv3::Transaction::reset_key(std::string const& newkey) { - key = newkey; -} +void etcdv3::Transaction::reset_key(std::string const& newkey) { key = newkey; } -void etcdv3::Transaction::init_compare(CompareResult result, CompareTarget target){ - Compare* compare = txn_request->add_compare(); - compare->set_result(detail::to_compare_result(result)); - compare->set_target(detail::to_compare_target(target)); - compare->set_key(key); +void etcdv3::Transaction::init_compare(CompareResult result, + CompareTarget target) { + Compare* compare = txn_request->add_compare(); + compare->set_result(detail::to_compare_result(result)); + compare->set_target(detail::to_compare_target(target)); + compare->set_key(key); - compare->set_version(0); + compare->set_version(0); } -void etcdv3::Transaction::init_compare(std::string const& old_value, CompareResult result, CompareTarget target){ - Compare* compare = txn_request->add_compare(); - compare->set_result(detail::to_compare_result(result)); - compare->set_target(detail::to_compare_target(target)); - compare->set_key(key); +void etcdv3::Transaction::init_compare(std::string const& old_value, + CompareResult result, + CompareTarget target) { + Compare* compare = txn_request->add_compare(); + compare->set_result(detail::to_compare_result(result)); + compare->set_target(detail::to_compare_target(target)); + compare->set_key(key); - compare->set_value(old_value); + compare->set_value(old_value); } -void etcdv3::Transaction::init_compare(int64_t old_index, CompareResult result, CompareTarget target){ - Compare* compare = txn_request->add_compare(); - compare->set_result(detail::to_compare_result(result)); - compare->set_target(detail::to_compare_target(target)); - compare->set_key(key); +void etcdv3::Transaction::init_compare(int64_t old_index, CompareResult result, + CompareTarget target) { + Compare* compare = txn_request->add_compare(); + compare->set_result(detail::to_compare_result(result)); + compare->set_target(detail::to_compare_target(target)); + compare->set_key(key); - compare->set_mod_revision(old_index); + compare->set_mod_revision(old_index); } /** * get key on failure */ -void etcdv3::Transaction::setup_basic_failure_operation(std::string const& key) { - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - RequestOp* req_failure = txn_request->add_failure(); - req_failure->set_allocated_request_range(get_request.release()); +void etcdv3::Transaction::setup_basic_failure_operation( + std::string const& key) { + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + RequestOp* req_failure = txn_request->add_failure(); + req_failure->set_allocated_request_range(get_request.release()); } /** * get key on failure, get key before put, modify and then get updated key */ -void etcdv3::Transaction::setup_set_failure_operation(std::string const &key, std::string const &value, int64_t leaseid) { - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(value); - put_request->set_prev_kv(true); - put_request->set_lease(leaseid); - RequestOp* req_failure = txn_request->add_failure(); - req_failure->set_allocated_request_put(put_request.release()); - - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - req_failure = txn_request->add_failure(); - req_failure->set_allocated_request_range(get_request.release()); +void etcdv3::Transaction::setup_set_failure_operation(std::string const& key, + std::string const& value, + int64_t leaseid) { + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(value); + put_request->set_prev_kv(true); + put_request->set_lease(leaseid); + RequestOp* req_failure = txn_request->add_failure(); + req_failure->set_allocated_request_put(put_request.release()); + + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + req_failure = txn_request->add_failure(); + req_failure->set_allocated_request_range(get_request.release()); } /** * add key and then get new value of key */ -void etcdv3::Transaction::setup_basic_create_sequence(std::string const& key, std::string const& value, int64_t leaseid) { - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(value); - put_request->set_prev_kv(true); - put_request->set_lease(leaseid); - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_put(put_request.release()); - - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - req_success = txn_request->add_success(); - req_success->set_allocated_request_range(get_request.release()); +void etcdv3::Transaction::setup_basic_create_sequence(std::string const& key, + std::string const& value, + int64_t leaseid) { + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(value); + put_request->set_prev_kv(true); + put_request->set_lease(leaseid); + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_put(put_request.release()); + + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + req_success = txn_request->add_success(); + req_success->set_allocated_request_range(get_request.release()); } /** * get key value then modify and get new value */ -void etcdv3::Transaction::setup_compare_and_swap_sequence(std::string const& value, int64_t leaseid) { - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(value); - put_request->set_prev_kv(true); - put_request->set_lease(leaseid); - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_put(put_request.release()); - - std::unique_ptr get_request(new RangeRequest()); - get_request->set_key(key); - req_success = txn_request->add_success(); - req_success->set_allocated_request_range(get_request.release()); +void etcdv3::Transaction::setup_compare_and_swap_sequence( + std::string const& value, int64_t leaseid) { + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(value); + put_request->set_prev_kv(true); + put_request->set_lease(leaseid); + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_put(put_request.release()); + + std::unique_ptr get_request(new RangeRequest()); + get_request->set_key(key); + req_success = txn_request->add_success(); + req_success->set_allocated_request_range(get_request.release()); } /** * get key, delete */ -void etcdv3::Transaction::setup_delete_sequence(std::string const &key, std::string const &range_end, bool recursive) { - std::unique_ptr del_request(new DeleteRangeRequest()); - del_request->set_key(key); - del_request->set_prev_kv(true); - if(recursive) - { - del_request->set_range_end(range_end); - } +void etcdv3::Transaction::setup_delete_sequence(std::string const& key, + std::string const& range_end, + bool recursive) { + std::unique_ptr del_request(new DeleteRangeRequest()); + del_request->set_key(key); + del_request->set_prev_kv(true); + if (recursive) { + del_request->set_range_end(range_end); + } - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_delete_range(del_request.release()); + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_delete_range(del_request.release()); } /** * get key, delete */ -void etcdv3::Transaction::setup_delete_failure_operation(std::string const &key, std::string const &range_end, bool recursive) { - std::unique_ptr get_request(new RangeRequest()); - std::unique_ptr del_request(new DeleteRangeRequest()); - get_request.reset(new RangeRequest()); - get_request->set_key(key); - if(recursive) - { - get_request->set_range_end(range_end); - get_request->set_sort_target(RangeRequest::SortTarget::RangeRequest_SortTarget_KEY); - get_request->set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND); - } - RequestOp* req_failure = txn_request->add_failure(); - req_failure->set_allocated_request_range(get_request.release()); - - del_request.reset(new DeleteRangeRequest()); - del_request->set_key(key); - if(recursive) - { - del_request->set_range_end(range_end); - } - - req_failure = txn_request->add_failure(); - req_failure->set_allocated_request_delete_range(del_request.release()); -} - -void etcdv3::Transaction::setup_compare_and_delete_operation(std::string const& key) { - std::unique_ptr del_request(new DeleteRangeRequest()); - del_request->set_key(key); - del_request->set_prev_kv(true); - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_delete_range(del_request.release()); -} - -void etcdv3::Transaction::setup_put(std::string const &key, std::string const &value) { - std::unique_ptr put_request(new PutRequest()); - put_request->set_key(key); - put_request->set_value(value); - put_request->set_prev_kv(false); - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_put(put_request.release()); -} - -void etcdv3::Transaction::setup_delete(std::string const &key) { - std::unique_ptr del_request(new DeleteRangeRequest()); - del_request->set_key(key); - del_request->set_prev_kv(false); - - RequestOp* req_success = txn_request->add_success(); - req_success->set_allocated_request_delete_range(del_request.release()); -} - -etcdv3::Transaction::~Transaction() { -} +void etcdv3::Transaction::setup_delete_failure_operation( + std::string const& key, std::string const& range_end, bool recursive) { + std::unique_ptr get_request(new RangeRequest()); + std::unique_ptr del_request(new DeleteRangeRequest()); + get_request.reset(new RangeRequest()); + get_request->set_key(key); + if (recursive) { + get_request->set_range_end(range_end); + get_request->set_sort_target( + RangeRequest::SortTarget::RangeRequest_SortTarget_KEY); + get_request->set_sort_order( + RangeRequest::SortOrder::RangeRequest_SortOrder_ASCEND); + } + RequestOp* req_failure = txn_request->add_failure(); + req_failure->set_allocated_request_range(get_request.release()); + + del_request.reset(new DeleteRangeRequest()); + del_request->set_key(key); + if (recursive) { + del_request->set_range_end(range_end); + } + + req_failure = txn_request->add_failure(); + req_failure->set_allocated_request_delete_range(del_request.release()); +} + +void etcdv3::Transaction::setup_compare_and_delete_operation( + std::string const& key) { + std::unique_ptr del_request(new DeleteRangeRequest()); + del_request->set_key(key); + del_request->set_prev_kv(true); + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_delete_range(del_request.release()); +} + +void etcdv3::Transaction::setup_put(std::string const& key, + std::string const& value) { + std::unique_ptr put_request(new PutRequest()); + put_request->set_key(key); + put_request->set_value(value); + put_request->set_prev_kv(false); + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_put(put_request.release()); +} + +void etcdv3::Transaction::setup_delete(std::string const& key) { + std::unique_ptr del_request(new DeleteRangeRequest()); + del_request->set_key(key); + del_request->set_prev_kv(false); + + RequestOp* req_success = txn_request->add_success(); + req_success->set_allocated_request_delete_range(del_request.release()); +} + +etcdv3::Transaction::~Transaction() {} diff --git a/src/v3/V3Response.cpp b/src/v3/V3Response.cpp index c35108e..21a235f 100644 --- a/src/v3/V3Response.cpp +++ b/src/v3/V3Response.cpp @@ -1,118 +1,81 @@ #include "etcd/v3/V3Response.hpp" #include "etcd/v3/action_constants.hpp" -void etcdv3::V3Response::set_error_code(int code) -{ - error_code = code; -} +void etcdv3::V3Response::set_error_code(int code) { error_code = code; } -void etcdv3::V3Response::set_error_message(std::string msg) -{ +void etcdv3::V3Response::set_error_message(std::string msg) { error_message = msg; } -int64_t etcdv3::V3Response::get_index() const -{ - return index; -} +int64_t etcdv3::V3Response::get_index() const { return index; } -std::string const & etcdv3::V3Response::get_action() const -{ - return action; -} +std::string const& etcdv3::V3Response::get_action() const { return action; } -int etcdv3::V3Response::get_error_code() const -{ - return error_code; -} +int etcdv3::V3Response::get_error_code() const { return error_code; } -std::string const & etcdv3::V3Response::get_error_message() const -{ +std::string const& etcdv3::V3Response::get_error_message() const { return error_message; } -void etcdv3::V3Response::set_action(std::string action) -{ +void etcdv3::V3Response::set_action(std::string action) { this->action = action; } -std::vector const & etcdv3::V3Response::get_values() const -{ +std::vector const& etcdv3::V3Response::get_values() const { return values; } -std::vector const & etcdv3::V3Response::get_prev_values() const -{ +std::vector const& etcdv3::V3Response::get_prev_values() + const { return prev_values; } -etcdv3::KeyValue const & etcdv3::V3Response::get_value() const -{ - return value; -} +etcdv3::KeyValue const& etcdv3::V3Response::get_value() const { return value; } -etcdv3::KeyValue const & etcdv3::V3Response::get_prev_value() const -{ +etcdv3::KeyValue const& etcdv3::V3Response::get_prev_value() const { return prev_value; } -bool etcdv3::V3Response::has_values() const -{ - return values.size() > 0; -} +bool etcdv3::V3Response::has_values() const { return values.size() > 0; } -int64_t etcdv3::V3Response::get_compact_revision() const -{ +int64_t etcdv3::V3Response::get_compact_revision() const { return compact_revision; } -void etcdv3::V3Response::set_compact_revision(const int64_t compact_revision) -{ +void etcdv3::V3Response::set_compact_revision(const int64_t compact_revision) { this->compact_revision = compact_revision; } -int64_t etcdv3::V3Response::get_watch_id() const -{ - return watch_id; -} +int64_t etcdv3::V3Response::get_watch_id() const { return watch_id; } -void etcdv3::V3Response::set_watch_id(const int64_t watch_id) -{ +void etcdv3::V3Response::set_watch_id(const int64_t watch_id) { this->watch_id = watch_id; } -void etcdv3::V3Response::set_lock_key(std::string const &key) { +void etcdv3::V3Response::set_lock_key(std::string const& key) { this->lock_key = key; } -std::string const & etcdv3::V3Response::get_lock_key() const { +std::string const& etcdv3::V3Response::get_lock_key() const { return this->lock_key; } -void etcdv3::V3Response::set_name(std::string const &name) { +void etcdv3::V3Response::set_name(std::string const& name) { this->name = name; } -std::string const & etcdv3::V3Response::get_name() const { - return this->name; -} +std::string const& etcdv3::V3Response::get_name() const { return this->name; } -std::vector const & etcdv3::V3Response::get_events() const { +std::vector const& etcdv3::V3Response::get_events() const { return this->events; } -uint64_t etcdv3::V3Response::get_cluster_id() const { - return this->cluster_id; -} +uint64_t etcdv3::V3Response::get_cluster_id() const { return this->cluster_id; } -uint64_t etcdv3::V3Response::get_member_id() const { - return this->member_id; -} +uint64_t etcdv3::V3Response::get_member_id() const { return this->member_id; } -uint64_t etcdv3::V3Response::get_raft_term() const { - return this->raft_term; -} +uint64_t etcdv3::V3Response::get_raft_term() const { return this->raft_term; } -std::vector const & etcdv3::V3Response::get_leases() const { +std::vector const& etcdv3::V3Response::get_leases() const { return this->leases; } diff --git a/src/v3/action_constants.cpp b/src/v3/action_constants.cpp index 7f1a0e7..dd82f50 100644 --- a/src/v3/action_constants.cpp +++ b/src/v3/action_constants.cpp @@ -1,48 +1,48 @@ #include "etcd/v3/action_constants.hpp" -char const * etcdv3::CREATE_ACTION = "create"; -char const * etcdv3::COMPARESWAP_ACTION = "compareAndSwap"; -char const * etcdv3::UPDATE_ACTION = "update"; -char const * etcdv3::SET_ACTION = "set"; -char const * etcdv3::GET_ACTION = "get"; -char const * etcdv3::PUT_ACTION = "put"; -char const * etcdv3::DELETE_ACTION = "delete"; -char const * etcdv3::COMPAREDELETE_ACTION = "compareAndDelete"; -char const * etcdv3::LOCK_ACTION = "lock"; -char const * etcdv3::UNLOCK_ACTION = "unlock"; -char const * etcdv3::TXN_ACTION = "txn"; -char const * etcdv3::WATCH_ACTION = "watch"; +char const* etcdv3::CREATE_ACTION = "create"; +char const* etcdv3::COMPARESWAP_ACTION = "compareAndSwap"; +char const* etcdv3::UPDATE_ACTION = "update"; +char const* etcdv3::SET_ACTION = "set"; +char const* etcdv3::GET_ACTION = "get"; +char const* etcdv3::PUT_ACTION = "put"; +char const* etcdv3::DELETE_ACTION = "delete"; +char const* etcdv3::COMPAREDELETE_ACTION = "compareAndDelete"; +char const* etcdv3::LOCK_ACTION = "lock"; +char const* etcdv3::UNLOCK_ACTION = "unlock"; +char const* etcdv3::TXN_ACTION = "txn"; +char const* etcdv3::WATCH_ACTION = "watch"; -char const * etcdv3::LEASEGRANT = "leasegrant"; -char const * etcdv3::LEASEREVOKE = "leaserevoke"; -char const * etcdv3::LEASEKEEPALIVE = "leasekeepalive"; -char const * etcdv3::LEASETIMETOLIVE = "leasetimetolive"; -char const * etcdv3::LEASELEASES = "leaseleases"; +char const* etcdv3::LEASEGRANT = "leasegrant"; +char const* etcdv3::LEASEREVOKE = "leaserevoke"; +char const* etcdv3::LEASEKEEPALIVE = "leasekeepalive"; +char const* etcdv3::LEASETIMETOLIVE = "leasetimetolive"; +char const* etcdv3::LEASELEASES = "leaseleases"; -char const * etcdv3::CAMPAIGN_ACTION = "campaign"; -char const * etcdv3::PROCLAIM_ACTION = "preclaim"; -char const * etcdv3::LEADER_ACTION = "leader"; -char const * etcdv3::OBSERVE_ACTION = "obverse"; -char const * etcdv3::RESIGN_ACTION = "resign"; +char const* etcdv3::CAMPAIGN_ACTION = "campaign"; +char const* etcdv3::PROCLAIM_ACTION = "preclaim"; +char const* etcdv3::LEADER_ACTION = "leader"; +char const* etcdv3::OBSERVE_ACTION = "obverse"; +char const* etcdv3::RESIGN_ACTION = "resign"; // see: noPrefixEnd in etcd, however c++ doesn't allows naive '\0' inside // a string, thus we use std::string(1, '\x00') as the constructor. std::string const etcdv3::NUL = std::string(1, '\x00'); -char const * etcdv3::KEEPALIVE_CREATE = "keepalive create"; -char const * etcdv3::KEEPALIVE_WRITE = "keepalive write"; -char const * etcdv3::KEEPALIVE_READ = "keepalive read"; -char const * etcdv3::KEEPALIVE_DONE = "keepalive done"; -char const * etcdv3::KEEPALIVE_FINISH = "keepalive finish"; +char const* etcdv3::KEEPALIVE_CREATE = "keepalive create"; +char const* etcdv3::KEEPALIVE_WRITE = "keepalive write"; +char const* etcdv3::KEEPALIVE_READ = "keepalive read"; +char const* etcdv3::KEEPALIVE_DONE = "keepalive done"; +char const* etcdv3::KEEPALIVE_FINISH = "keepalive finish"; -char const * etcdv3::WATCH_CREATE = "watch create"; -char const * etcdv3::WATCH_WRITE = "watch write"; -char const * etcdv3::WATCH_WRITE_CANCEL = "watch write cancel"; -char const * etcdv3::WATCH_WRITES_DONE = "watch writes done"; -char const * etcdv3::WATCH_FINISH = "watch finish"; +char const* etcdv3::WATCH_CREATE = "watch create"; +char const* etcdv3::WATCH_WRITE = "watch write"; +char const* etcdv3::WATCH_WRITE_CANCEL = "watch write cancel"; +char const* etcdv3::WATCH_WRITES_DONE = "watch writes done"; +char const* etcdv3::WATCH_FINISH = "watch finish"; -char const * etcdv3::ELECTION_OBSERVE_CREATE = "observe create"; -char const * etcdv3::ELECTION_OBSERVE_FINISH = "observe finish"; +char const* etcdv3::ELECTION_OBSERVE_CREATE = "observe create"; +char const* etcdv3::ELECTION_OBSERVE_FINISH = "observe finish"; const int etcdv3::ERROR_GRPC_OK = 0; const int etcdv3::ERROR_GRPC_CANCELLED = 1; diff --git a/tst/AuthTest.cpp b/tst/AuthTest.cpp index 5a4b91d..01ab30f 100644 --- a/tst/AuthTest.cpp +++ b/tst/AuthTest.cpp @@ -5,22 +5,21 @@ #include "etcd/Client.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("setup with auth") -{ - etcd::Client *etcd = etcd::Client::WithUser(etcd_url, "root", "root"); +TEST_CASE("setup with auth") { + etcd::Client* etcd = etcd::Client::WithUser(etcd_url, "root", "root"); etcd->rmdir("/test", true).wait(); } -TEST_CASE("add a new key after authenticate") -{ - etcd::Client *etcd = etcd::Client::WithUser(etcd_url, "root", "root"); +TEST_CASE("add a new key after authenticate") { + etcd::Client* etcd = etcd::Client::WithUser(etcd_url, "root", "root"); etcd->rmdir("/test", true).wait(); etcd::Response resp = etcd->add("/test/key1", "42").get(); REQUIRE(0 == resp.error_code()); CHECK("create" == resp.action()); - etcd::Value const & val = resp.value(); + etcd::Value const& val = resp.value(); CHECK("42" == val.as_string()); CHECK("/test/key1" == val.key()); CHECK(!val.is_dir()); @@ -28,24 +27,28 @@ TEST_CASE("add a new key after authenticate") CHECK(0 < val.modified_index()); CHECK(1 == val.version()); CHECK(0 < resp.index()); - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "43").get().error_code()); // Key already exists - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "42").get().error_code()); // Key already exists - CHECK("etcd-cpp-apiv3: key already exists" == etcd->add("/test/key1", "42").get().error_message()); + CHECK( + etcd::ERROR_KEY_ALREADY_EXISTS == + etcd->add("/test/key1", "43").get().error_code()); // Key already exists + CHECK( + etcd::ERROR_KEY_ALREADY_EXISTS == + etcd->add("/test/key1", "42").get().error_code()); // Key already exists + CHECK("etcd-cpp-apiv3: key already exists" == + etcd->add("/test/key1", "42").get().error_message()); } -TEST_CASE("read a value from etcd") -{ - etcd::Client *etcd = etcd::Client::WithUser(etcd_url, "root", "root"); +TEST_CASE("read a value from etcd") { + etcd::Client* etcd = etcd::Client::WithUser(etcd_url, "root", "root"); etcd::Response resp = etcd->get("/test/key1").get(); CHECK("get" == resp.action()); REQUIRE(resp.is_ok()); REQUIRE(0 == resp.error_code()); CHECK("42" == resp.value().as_string()); - CHECK("" == etcd->get("/test").get().value().as_string()); // key points to a directory + CHECK("" == etcd->get("/test").get().value().as_string()); // key points to a + // directory } -TEST_CASE("cleanup") -{ - etcd::Client *etcd = etcd::Client::WithUser(etcd_url, "root", "root"); +TEST_CASE("cleanup") { + etcd::Client* etcd = etcd::Client::WithUser(etcd_url, "root", "root"); REQUIRE(0 == etcd->rmdir("/test", true).get().error_code()); } diff --git a/tst/CampaignTest.cpp b/tst/CampaignTest.cpp index 2893824..4f53dff 100644 --- a/tst/CampaignTest.cpp +++ b/tst/CampaignTest.cpp @@ -11,7 +11,7 @@ #include "etcd/Value.hpp" static std::string etcd_uri = etcdv3::detail::resolve_etcd_endpoints( - "http://127.0.0.1:2379,http://127.0.0.1:2479,http://127.0.0.1:2579"); + "http://127.0.0.1:2379,http://127.0.0.1:2479,http://127.0.0.1:2579"); TEST_CASE("campaign and leadership using keepalive") { etcd::Client etcd(etcd_uri); @@ -39,13 +39,14 @@ TEST_CASE("campaign and leadership using keepalive") { std::cout << "finish leader" << std::endl; - auto resp3 = etcd.resign("/leader", resp1.value().lease(), resp1.value().key(), resp1.value().created_index()).get(); + auto resp3 = etcd.resign("/leader", resp1.value().lease(), + resp1.value().key(), resp1.value().created_index()) + .get(); CHECK(0 == resp3.error_code()); std::cout << "finish resign" << std::endl; } - TEST_CASE("concurrent campaign with grpc timeout") { std::string value1 = std::string("192.168.1.6:1880"); std::string value2 = std::string("192.168.1.6:1890"); @@ -60,7 +61,9 @@ TEST_CASE("concurrent campaign with grpc timeout") { std::this_thread::sleep_for(std::chrono::seconds(10)); // resign - auto resp2 = etcd.resign("/leader", resp1.value().lease(), resp1.value().key(), resp1.value().created_index()).get(); + auto resp2 = etcd.resign("/leader", resp1.value().lease(), + resp1.value().key(), resp1.value().created_index()) + .get(); CHECK(0 == resp2.error_code()); }; @@ -74,7 +77,7 @@ TEST_CASE("concurrent campaign with grpc timeout") { std::this_thread::sleep_for(std::chrono::seconds(3)); auto resp1 = etcd.campaign("/leader", lease_id, value2).get(); - std::cout <WaitOnce(); - std::cout << "observe " << resp.value().key() << " as the leader: " << resp.value().as_string() << std::endl; + std::cout << "observe " << resp.value().key() + << " as the leader: " << resp.value().as_string() << std::endl; } std::cout << "finish the observe" << std::endl; // cancel the observers @@ -109,8 +109,7 @@ TEST_CASE("campaign and observe") observer_thread.join(); } -TEST_CASE("cleanup") -{ +TEST_CASE("cleanup") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).get(); } diff --git a/tst/EtcdSyncTest.cpp b/tst/EtcdSyncTest.cpp index 84118ef..1dee207 100644 --- a/tst/EtcdSyncTest.cpp +++ b/tst/EtcdSyncTest.cpp @@ -5,38 +5,41 @@ #include "etcd/SyncClient.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("sync operations") -{ +TEST_CASE("sync operations") { etcd::SyncClient etcd(etcd_url); etcd.rmdir("/test", true); // add CHECK(0 == etcd.add("/test/key1", "42").error_code()); - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "42").error_code()); // Key already exists + CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == + etcd.add("/test/key1", "42").error_code()); // Key already exists CHECK("42" == etcd.get("/test/key1").value().as_string()); // modify CHECK(0 == etcd.modify("/test/key1", "43").error_code()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.modify("/test/key2", "43").error_code()); // Key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.modify("/test/key2", "43").error_code()); // Key not found CHECK("43" == etcd.modify("/test/key1", "42").prev_value().as_string()); // set - CHECK(0 == etcd.set("/test/key1", "43").error_code()); // overwrite - CHECK(0 == etcd.set("/test/key2", "43").error_code()); // create new + CHECK(0 == etcd.set("/test/key1", "43").error_code()); // overwrite + CHECK(0 == etcd.set("/test/key2", "43").error_code()); // create new CHECK("43" == etcd.set("/test/key2", "44").prev_value().as_string()); - CHECK("" == etcd.set("/test/key3", "44").prev_value().as_string()); + CHECK("" == etcd.set("/test/key3", "44").prev_value().as_string()); // get CHECK("43" == etcd.get("/test/key1").value().as_string()); CHECK("44" == etcd.get("/test/key2").value().as_string()); CHECK("44" == etcd.get("/test/key3").value().as_string()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.get("/test/key4").error_code()); // key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.get("/test/key4").error_code()); // key not found // rm CHECK(3 == etcd.ls("/test").keys().size()); - CHECK(0 == etcd.rm("/test/key1").error_code()); + CHECK(0 == etcd.rm("/test/key1").error_code()); CHECK(2 == etcd.ls("/test").keys().size()); // ls @@ -51,71 +54,75 @@ TEST_CASE("sync operations") CHECK(2 == etcd.keys("/test/new_dir").keys().size()); // rmdir - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").error_code()); // key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.rmdir("/test/new_dir").error_code()); // key not found CHECK(0 == etcd.rmdir("/test/new_dir", true).error_code()); // compare and swap etcd.set("/test/key1", "42"); int64_t index = etcd.modify_if("/test/key1", "43", "42").index(); - CHECK(etcd::ERROR_COMPARE_FAILED == etcd.modify_if("/test/key1", "44", "42").error_code()); + CHECK(etcd::ERROR_COMPARE_FAILED == + etcd.modify_if("/test/key1", "44", "42").error_code()); REQUIRE(etcd.modify_if("/test/key1", "44", index).is_ok()); - CHECK(etcd::ERROR_COMPARE_FAILED == etcd.modify_if("/test/key1", "45", index).error_code()); + CHECK(etcd::ERROR_COMPARE_FAILED == + etcd.modify_if("/test/key1", "45", index).error_code()); // atomic compare-and-delete based on prevValue etcd.set("/test/key1", "42"); - CHECK(etcd::ERROR_COMPARE_FAILED == etcd.rm_if("/test/key1", "43").error_code()); + CHECK(etcd::ERROR_COMPARE_FAILED == + etcd.rm_if("/test/key1", "43").error_code()); CHECK(0 == etcd.rm_if("/test/key1", "42").error_code()); // atomic compare-and-delete based on prevIndex index = etcd.set("/test/key1", "42").index(); - CHECK(etcd::ERROR_COMPARE_FAILED == etcd.rm_if("/test/key1", index - 1).error_code()); + CHECK(etcd::ERROR_COMPARE_FAILED == + etcd.rm_if("/test/key1", index - 1).error_code()); CHECK(0 == etcd.rm_if("/test/key1", index).error_code()); - //leasegrant + // leasegrant etcd::Response res = etcd.leasegrant(60); REQUIRE(res.is_ok()); CHECK(60 == res.value().ttl()); - CHECK(0 < res.value().lease()); + CHECK(0 < res.value().lease()); int64_t leaseid = res.value().lease(); - //add with lease + // add with lease res = etcd.add("/test/key1111", "43", leaseid); - REQUIRE(0 == res.error_code()); // overwrite + REQUIRE(0 == res.error_code()); // overwrite CHECK("create" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); - //set with lease + // set with lease res = etcd.set("/test/key1", "43", leaseid); REQUIRE(0 == res.error_code()); CHECK("set" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); - //modify with lease + // modify with lease res = etcd.modify("/test/key1", "44", leaseid); - REQUIRE(0 == res.error_code()); + REQUIRE(0 == res.error_code()); CHECK("update" == res.action()); - CHECK(leaseid == res.value().lease()); - CHECK("44" == res.value().as_string()); + CHECK(leaseid == res.value().lease()); + CHECK("44" == res.value().as_string()); res = etcd.modify_if("/test/key1", "45", "44", leaseid); index = res.index(); REQUIRE(res.is_ok()); CHECK("compareAndSwap" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); CHECK("45" == res.value().as_string()); res = etcd.modify_if("/test/key1", "44", index, leaseid); index = res.index(); REQUIRE(res.is_ok()); CHECK("compareAndSwap" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); CHECK("44" == res.value().as_string()); REQUIRE(0 == etcd.rmdir("/test", true).error_code()); } -TEST_CASE("wait for a value change") -{ +TEST_CASE("wait for a value change") { etcd::SyncClient etcd(etcd_url); etcd.set("/test/key1", "42"); @@ -132,8 +139,7 @@ TEST_CASE("wait for a value change") REQUIRE(0 == etcd.rmdir("/test", true).error_code()); } -TEST_CASE("wait for a directory change") -{ +TEST_CASE("wait for a directory change") { etcd::SyncClient etcd(etcd_url); std::thread watch_thrd1([&]() { @@ -159,8 +165,7 @@ TEST_CASE("wait for a directory change") REQUIRE(0 == etcd.rmdir("/test", true).error_code()); } -TEST_CASE("watch changes in the past") -{ +TEST_CASE("watch changes in the past") { etcd::SyncClient etcd(etcd_url); int64_t index = etcd.set("/test/key1", "42").index(); diff --git a/tst/EtcdTest.cpp b/tst/EtcdTest.cpp index f9d040a..7739b76 100644 --- a/tst/EtcdTest.cpp +++ b/tst/EtcdTest.cpp @@ -7,22 +7,21 @@ #include "etcd/Client.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("setup") -{ +TEST_CASE("setup") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); } -TEST_CASE("add a new key") -{ +TEST_CASE("add a new key") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); etcd::Response resp = etcd.add("/test/key1", "42").get(); REQUIRE(0 == resp.error_code()); CHECK("create" == resp.action()); - etcd::Value const & val = resp.value(); + etcd::Value const& val = resp.value(); CHECK("42" == val.as_string()); CHECK("/test/key1" == val.key()); CHECK(!val.is_dir()); @@ -30,32 +29,35 @@ TEST_CASE("add a new key") CHECK(0 < val.modified_index()); CHECK(1 == val.version()); CHECK(0 < resp.index()); - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "43").get().error_code()); // Key already exists - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd.add("/test/key1", "42").get().error_code()); // Key already exists - CHECK("etcd-cpp-apiv3: key already exists" == etcd.add("/test/key1", "42").get().error_message()); + CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == + etcd.add("/test/key1", "43").get().error_code()); // Key already exists + CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == + etcd.add("/test/key1", "42").get().error_code()); // Key already exists + CHECK("etcd-cpp-apiv3: key already exists" == + etcd.add("/test/key1", "42").get().error_message()); } -TEST_CASE("read a value from etcd") -{ +TEST_CASE("read a value from etcd") { etcd::Client etcd(etcd_url); etcd::Response resp = etcd.get("/test/key1").get(); CHECK("get" == resp.action()); REQUIRE(resp.is_ok()); REQUIRE(0 == resp.error_code()); CHECK("42" == resp.value().as_string()); - CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a directory + CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a + // directory } -TEST_CASE("simplified read") -{ +TEST_CASE("simplified read") { etcd::Client etcd(etcd_url); CHECK("42" == etcd.get("/test/key1").get().value().as_string()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.get("/test/key2").get().error_code()); // Key not found - CHECK("" == etcd.get("/test/key2").get().value().as_string()); // Key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.get("/test/key2").get().error_code()); // Key not found + CHECK("" == + etcd.get("/test/key2").get().value().as_string()); // Key not found } -TEST_CASE("modify a key") -{ +TEST_CASE("modify a key") { etcd::Client etcd(etcd_url); // get @@ -66,9 +68,10 @@ TEST_CASE("modify a key") // modify resp = etcd.modify("/test/key1", "43").get(); - REQUIRE(0 == resp.error_code()); // overwrite + REQUIRE(0 == resp.error_code()); // overwrite CHECK("update" == resp.action()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.modify("/test/key2", "43").get().error_code()); // Key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.modify("/test/key2", "43").get().error_code()); // Key not found CHECK("43" == etcd.modify("/test/key1", "42").get().prev_value().as_string()); // check previous @@ -77,28 +80,26 @@ TEST_CASE("modify a key") CHECK("42" == resp.value().as_string()); } -TEST_CASE("set a key") -{ +TEST_CASE("set a key") { etcd::Client etcd(etcd_url); etcd::Response resp = etcd.set("/test/key1", "43").get(); - REQUIRE(0 == resp.error_code()); // overwrite + REQUIRE(0 == resp.error_code()); // overwrite CHECK("set" == resp.action()); - CHECK(0 == etcd.set("/test/key2", "43").get().error_code()); // create new + CHECK(0 == etcd.set("/test/key2", "43").get().error_code()); // create new CHECK("43" == etcd.set("/test/key2", "44").get().prev_value().as_string()); CHECK("" == etcd.set("/test/key3", "44").get().prev_value().as_string()); - CHECK(0 == etcd.set("/test", "42").get().error_code()); // Not a file + CHECK(0 == etcd.set("/test", "42").get().error_code()); // Not a file - //set with ttl + // set with ttl resp = etcd.set("/test/key1", "50", 10).get(); - REQUIRE(0 == resp.error_code()); // overwrite + REQUIRE(0 == resp.error_code()); // overwrite CHECK("set" == resp.action()); CHECK("43" == resp.prev_value().as_string()); CHECK("50" == resp.value().as_string()); - CHECK( 0 < resp.value().lease()); + CHECK(0 < resp.value().lease()); } -TEST_CASE("atomic compare-and-swap") -{ +TEST_CASE("atomic compare-and-swap") { etcd::Client etcd(etcd_url); etcd.set("/test/key1", "42").wait(); @@ -121,8 +122,7 @@ TEST_CASE("atomic compare-and-swap") CHECK("etcd-cpp-apiv3: key not found" == res.error_message()); } -TEST_CASE("delete a value") -{ +TEST_CASE("delete a value") { etcd::Client etcd(etcd_url); etcd::Response resp = etcd.rm("/test/key11111").get(); CHECK(!resp.is_ok()); @@ -139,20 +139,19 @@ TEST_CASE("delete a value") resp = etcd.rm("/test/key1").get(); CHECK("43" == resp.prev_value().as_string()); - CHECK( "/test/key1" == resp.prev_value().key()); - CHECK( create_index == resp.prev_value().created_index()); - CHECK( modify_index == resp.prev_value().modified_index()); - CHECK( version == resp.prev_value().version()); + CHECK("/test/key1" == resp.prev_value().key()); + CHECK(create_index == resp.prev_value().created_index()); + CHECK(modify_index == resp.prev_value().modified_index()); + CHECK(version == resp.prev_value().version()); CHECK("delete" == resp.action()); - CHECK( modify_index == resp.value().modified_index()); - CHECK( create_index == resp.value().created_index()); - CHECK( version == resp.value().version()); + CHECK(modify_index == resp.value().modified_index()); + CHECK(create_index == resp.value().created_index()); + CHECK(version == resp.value().version()); CHECK("" == resp.value().as_string()); - CHECK( "/test/key1" == resp.value().key()); + CHECK("/test/key1" == resp.value().key()); } -TEST_CASE("atomic compare-and-delete based on prevValue") -{ +TEST_CASE("atomic compare-and-delete based on prevValue") { etcd::Client etcd(etcd_url); etcd.set("/test/key1", "42").wait(); @@ -167,8 +166,7 @@ TEST_CASE("atomic compare-and-delete based on prevValue") CHECK("42" == res.prev_value().as_string()); } -TEST_CASE("atomic compare-and-delete based on prevIndex") -{ +TEST_CASE("atomic compare-and-delete based on prevIndex") { etcd::Client etcd(etcd_url); int64_t index = etcd.set("/test/key1", "42").get().index(); @@ -183,8 +181,7 @@ TEST_CASE("atomic compare-and-delete based on prevIndex") CHECK("42" == res.prev_value().as_string()); } -TEST_CASE("deep atomic compare-and-swap") -{ +TEST_CASE("deep atomic compare-and-swap") { etcd::Client etcd(etcd_url); etcd.set("/test/key1", "42").wait(); @@ -214,8 +211,7 @@ TEST_CASE("deep atomic compare-and-swap") CHECK("etcd-cpp-apiv3: compare failed" == res.error_message()); } -TEST_CASE("using binary keys and values, raw char pointer doesn't work") -{ +TEST_CASE("using binary keys and values, raw char pointer doesn't work") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); { @@ -244,12 +240,13 @@ TEST_CASE("using binary keys and values, raw char pointer doesn't work") } } -TEST_CASE("using binary keys and values, std::string is ok for \\0") -{ +TEST_CASE("using binary keys and values, std::string is ok for \\0") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); { - etcd::Response resp = etcd.put(std::string("/test/key1\0xyz", 14), std::string("42\0foo", 6)).get(); + etcd::Response resp = + etcd.put(std::string("/test/key1\0xyz", 14), std::string("42\0foo", 6)) + .get(); REQUIRE(resp.is_ok()); } { @@ -267,8 +264,7 @@ TEST_CASE("using binary keys and values, std::string is ok for \\0") } } -TEST_CASE("list a directory") -{ +TEST_CASE("list a directory") { etcd::Client etcd(etcd_url); CHECK(0 == etcd.ls("/test/new_dir").get().keys().size()); @@ -304,8 +300,7 @@ TEST_CASE("list a directory") CHECK(etcd.rmdir("/test/new_dir", true).get().is_ok()); } -TEST_CASE("list by range") -{ +TEST_CASE("list by range") { etcd::Client etcd(etcd_url); CHECK(0 == etcd.ls("/test/new_dir").get().keys().size()); @@ -315,13 +310,15 @@ TEST_CASE("list by range") etcd.set("/test/new_dir/key3", "value3").wait(); etcd.set("/test/new_dir/key4", "value4").wait(); - etcd::Response resp1 = etcd.ls("/test/new_dir/key1", "/test/new_dir/key3").get(); + etcd::Response resp1 = + etcd.ls("/test/new_dir/key1", "/test/new_dir/key3").get(); REQUIRE(resp1.is_ok()); CHECK("get" == resp1.action()); REQUIRE(2 == resp1.keys().size()); REQUIRE(2 == resp1.values().size()); - etcd::Response resp2 = etcd.ls("/test/new_dir/key1", "/test/new_dir/key4").get(); + etcd::Response resp2 = + etcd.ls("/test/new_dir/key1", "/test/new_dir/key4").get(); REQUIRE(resp2.is_ok()); CHECK("get" == resp2.action()); REQUIRE(3 == resp2.keys().size()); @@ -333,7 +330,10 @@ TEST_CASE("list by range") REQUIRE(4 == resp3.keys().size()); REQUIRE(4 == resp3.values().size()); - etcd::Response resp4 = etcd.ls("/test/new_dir/key1", etcdv3::detail::string_plus_one("/test/new_dir/key")).get(); + etcd::Response resp4 = + etcd.ls("/test/new_dir/key1", + etcdv3::detail::string_plus_one("/test/new_dir/key")) + .get(); REQUIRE(resp4.is_ok()); CHECK("get" == resp4.action()); REQUIRE(4 == resp4.keys().size()); @@ -344,8 +344,7 @@ TEST_CASE("list by range") CHECK(etcd.rmdir("/test/new_dir", true).get().is_ok()); } -TEST_CASE("list by range, w/o values") -{ +TEST_CASE("list by range, w/o values") { etcd::Client etcd(etcd_url); CHECK(0 == etcd.ls("/test/new_dir").get().keys().size()); @@ -355,14 +354,16 @@ TEST_CASE("list by range, w/o values") etcd.set("/test/new_dir/key3", "value3").wait(); etcd.set("/test/new_dir/key4", "value4").wait(); - etcd::Response resp1 = etcd.ls("/test/new_dir/key1", "/test/new_dir/key2").get(); + etcd::Response resp1 = + etcd.ls("/test/new_dir/key1", "/test/new_dir/key2").get(); REQUIRE(resp1.is_ok()); CHECK("get" == resp1.action()); REQUIRE(1 == resp1.keys().size()); REQUIRE(1 == resp1.values().size()); REQUIRE(resp1.values()[0].as_string() == "value1"); - etcd::Response resp2 = etcd.keys("/test/new_dir/key1", "/test/new_dir/key2").get(); + etcd::Response resp2 = + etcd.keys("/test/new_dir/key1", "/test/new_dir/key2").get(); REQUIRE(resp1.is_ok()); CHECK("get" == resp2.action()); REQUIRE(1 == resp2.keys().size()); @@ -372,15 +373,15 @@ TEST_CASE("list by range, w/o values") CHECK(etcd.rmdir("/test/new_dir", true).get().is_ok()); } -TEST_CASE("delete a directory") -{ +TEST_CASE("delete a directory") { etcd::Client etcd(etcd_url); etcd.set("/test/new_dir/key1", "value1").wait(); etcd.set("/test/new_dir/key2", "value2").wait(); etcd.set("/test/new_dir/key3", "value3").wait(); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").get().error_code()); // key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.rmdir("/test/new_dir").get().error_code()); // key not found etcd::Response resp = etcd.ls("/test/new_dir").get(); resp = etcd.rmdir("/test/new_dir", true).get(); @@ -391,7 +392,6 @@ TEST_CASE("delete a directory") CHECK("value1" == resp.value(0).as_string()); CHECK("value2" == resp.value(1).as_string()); - resp = etcd.rmdir("/test/dirnotfound", true).get(); CHECK(!resp.is_ok()); CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code()); @@ -403,8 +403,7 @@ TEST_CASE("delete a directory") CHECK("etcd-cpp-apiv3: key not found" == resp.error_message()); } -TEST_CASE("delete all keys with rmdir(\"\", true)") -{ +TEST_CASE("delete all keys with rmdir(\"\", true)") { etcd::Client etcd(etcd_url); etcd.rmdir("", true).wait(); @@ -417,11 +416,11 @@ TEST_CASE("delete all keys with rmdir(\"\", true)") CHECK(resp.values().size() == 3); } -TEST_CASE("delete by range") -{ +TEST_CASE("delete by range") { etcd::Client etcd(etcd_url); - CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").get().error_code()); // key not found + CHECK(etcd::ERROR_KEY_NOT_FOUND == + etcd.rmdir("/test/new_dir").get().error_code()); // key not found etcd::Response resp = etcd.ls("/test/new_dir").get(); etcd.set("/test/new_dir/key1", "value1").wait(); @@ -438,8 +437,7 @@ TEST_CASE("delete by range") CHECK("value2" == resp.value(1).as_string()); } -TEST_CASE("wait for a value change") -{ +TEST_CASE("wait for a value change") { etcd::Client etcd(etcd_url); etcd.set("/test/key1", "42").wait(); @@ -447,7 +445,7 @@ TEST_CASE("wait for a value change") CHECK(!res.is_done()); std::this_thread::sleep_for(std::chrono::seconds(1)); CHECK(!res.is_done()); - + etcd.set("/test/key1", "43").get(); std::this_thread::sleep_for(std::chrono::seconds(1)); REQUIRE(res.is_done()); @@ -456,8 +454,7 @@ TEST_CASE("wait for a value change") CHECK("42" == res.get().prev_value().as_string()); } -TEST_CASE("wait for a directory change") -{ +TEST_CASE("wait for a directory change") { etcd::Client etcd(etcd_url); pplx::task res = etcd.watch("/test", true); @@ -483,8 +480,7 @@ TEST_CASE("wait for a directory change") CHECK("45" == res2.get().value().as_string()); } -TEST_CASE("watch changes in the past") -{ +TEST_CASE("watch changes in the past") { etcd::Client etcd(etcd_url); REQUIRE(0 == etcd.rmdir("/test", true).get().error_code()); int64_t index = etcd.set("/test/key1", "42").get().index(); @@ -510,8 +506,7 @@ TEST_CASE("watch changes in the past") CHECK("45" == res.value().as_string()); } -TEST_CASE("watch range changes in the past") -{ +TEST_CASE("watch range changes in the past") { etcd::Client etcd(etcd_url); REQUIRE(0 == etcd.rmdir("/test", true).get().error_code()); int64_t index = etcd.set("/test/key1", "42").get().index(); @@ -542,53 +537,53 @@ TEST_CASE("watch multiple keys and use promise") { int64_t start_index = etcd.set("/test/key1", "value1").get().index(); etcd.set("/test/key2", "value2").get(); - pplx::task res = etcd.watch("/test", start_index, true) - .then([](pplx::task const &resp_task) -> size_t { - auto const &resp = resp_task.get(); - return resp.events().size(); - }); + pplx::task res = + etcd.watch("/test", start_index, true) + .then([](pplx::task const& resp_task) -> size_t { + auto const& resp = resp_task.get(); + return resp.events().size(); + }); size_t event_size = res.get(); CHECK(2 == event_size); } -TEST_CASE("lease grant") -{ +TEST_CASE("lease grant") { etcd::Client etcd(etcd_url); etcd::Response res = etcd.leasegrant(60).get(); REQUIRE(res.is_ok()); CHECK(60 == res.value().ttl()); - CHECK(0 < res.value().lease()); + CHECK(0 < res.value().lease()); int64_t leaseid = res.value().lease(); res = etcd.set("/test/key1", "43", leaseid).get(); - REQUIRE(0 == res.error_code()); // overwrite + REQUIRE(0 == res.error_code()); // overwrite CHECK("set" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); // change with lease id res = etcd.leasegrant(10).get(); leaseid = res.value().lease(); res = etcd.set("/test/key1", "43", leaseid).get(); - REQUIRE(0 == res.error_code()); // overwrite + REQUIRE(0 == res.error_code()); // overwrite CHECK("set" == res.action()); CHECK(leaseid == res.value().lease()); // failure to attach lease id - res = etcd.set("/test/key1", "43", leaseid+1).get(); + res = etcd.set("/test/key1", "43", leaseid + 1).get(); REQUIRE(!res.is_ok()); - REQUIRE(5 == res.error_code()); + REQUIRE(5 == res.error_code()); CHECK("etcdserver: requested lease not found" == res.error_message()); res = etcd.modify("/test/key1", "44", leaseid).get(); - REQUIRE(0 == res.error_code()); // overwrite + REQUIRE(0 == res.error_code()); // overwrite CHECK("update" == res.action()); - CHECK(leaseid == res.value().lease()); - CHECK("44" == res.value().as_string()); + CHECK(leaseid == res.value().lease()); + CHECK("44" == res.value().as_string()); // failure to attach invalid lease id - res = etcd.modify("/test/key1", "45", leaseid+1).get(); + res = etcd.modify("/test/key1", "45", leaseid + 1).get(); REQUIRE(!res.is_ok()); - REQUIRE(5 == res.error_code()); + REQUIRE(5 == res.error_code()); CHECK("etcdserver: requested lease not found" == res.error_message()); res = etcd.modify_if("/test/key1", "45", "44", leaseid).get(); @@ -598,9 +593,9 @@ TEST_CASE("lease grant") CHECK("45" == res.value().as_string()); // failure to attach invalid lease id - res = etcd.modify_if("/test/key1", "46", "45", leaseid+1).get(); + res = etcd.modify_if("/test/key1", "46", "45", leaseid + 1).get(); REQUIRE(!res.is_ok()); - REQUIRE(5 == res.error_code()); + REQUIRE(5 == res.error_code()); CHECK("etcdserver: requested lease not found" == res.error_message()); // succes with the correct index & lease id @@ -610,36 +605,35 @@ TEST_CASE("lease grant") CHECK("compareAndSwap" == res.action()); CHECK("44" == res.value().as_string()); - res = etcd.modify_if("/test/key1", "44", index, leaseid+1).get(); + res = etcd.modify_if("/test/key1", "44", index, leaseid + 1).get(); REQUIRE(!res.is_ok()); - REQUIRE(5 == res.error_code()); + REQUIRE(5 == res.error_code()); CHECK("etcdserver: requested lease not found" == res.error_message()); res = etcd.add("/test/key11111", "43", leaseid).get(); - REQUIRE(0 == res.error_code()); + REQUIRE(0 == res.error_code()); CHECK("create" == res.action()); - CHECK(leaseid == res.value().lease()); + CHECK(leaseid == res.value().lease()); - //failure to attach invalid lease id - res = etcd.set("/test/key11111", "43", leaseid+1).get(); + // failure to attach invalid lease id + res = etcd.set("/test/key11111", "43", leaseid + 1).get(); REQUIRE(!res.is_ok()); - REQUIRE(5 == res.error_code()); + REQUIRE(5 == res.error_code()); CHECK("etcdserver: requested lease not found" == res.error_message()); } -TEST_CASE("lease list") -{ +TEST_CASE("lease list") { etcd::Client etcd(etcd_url); etcd::Response res = etcd.leasegrant(60).get(); REQUIRE(res.is_ok()); CHECK(60 == res.value().ttl()); - CHECK(0 < res.value().lease()); + CHECK(0 < res.value().lease()); int64_t leaseid = res.value().lease(); etcd::Response leasesresp = etcd.leases().get(); if (leasesresp.is_ok()) { REQUIRE(leasesresp.is_ok()); - auto const &leases = leasesresp.leases(); + auto const& leases = leasesresp.leases(); REQUIRE(leases.size() > 0); CHECK(std::find(leases.begin(), leases.end(), leaseid) != leases.end()); } else { @@ -647,8 +641,7 @@ TEST_CASE("lease list") } } -TEST_CASE("cleanup") -{ +TEST_CASE("cleanup") { etcd::Client etcd(etcd_url); REQUIRE(0 == etcd.rmdir("/test", true).get().error_code()); } diff --git a/tst/ForkTest.cpp b/tst/ForkTest.cpp index 2f01915..bec7219 100644 --- a/tst/ForkTest.cpp +++ b/tst/ForkTest.cpp @@ -12,10 +12,10 @@ #include "etcd/Client.hpp" #include "etcd/KeepAlive.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("fork: set in child and get from self") -{ +TEST_CASE("fork: set in child and get from self") { pid_t pid = fork(); REQUIRE(pid >= 0); @@ -29,15 +29,15 @@ TEST_CASE("fork: set in child and get from self") etcd::Client etcd(etcd_url); size_t check = 0; while (check < 10) { - auto resp = etcd.get("/test/fork-key1").get(); - if (!resp.is_ok()) { - check += 1; - std::this_thread::sleep_for(std::chrono::seconds(1)); - continue; - } else { - CHECK(resp.value().as_string() == "fork: abcdefgh"); - break; - } + auto resp = etcd.get("/test/fork-key1").get(); + if (!resp.is_ok()) { + check += 1; + std::this_thread::sleep_for(std::chrono::seconds(1)); + continue; + } else { + CHECK(resp.value().as_string() == "fork: abcdefgh"); + break; + } } std::cout << "self: get finished ..." << std::endl; } diff --git a/tst/KeepAliveTest.cpp b/tst/KeepAliveTest.cpp index e405134..dbeea68 100644 --- a/tst/KeepAliveTest.cpp +++ b/tst/KeepAliveTest.cpp @@ -10,8 +10,8 @@ #include "etcd/SyncClient.hpp" #include "etcd/Value.hpp" -static std::string etcd_uri = etcdv3::detail::resolve_etcd_endpoints( - "http://127.0.0.1:2379,http://127.0.0.1:2479,http://127.0.0.1:2579"); +static std::string etcd_uri = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); TEST_CASE("keepalive revoke and check if alive") { etcd::Client etcd(etcd_uri); @@ -33,3 +33,30 @@ TEST_CASE("keepalive revoke and check if alive") { // expect keep_alive->Check() to throw exception REQUIRE_THROWS(keepalive->Check()); } + +TEST_CASE("keepalive won't expire") { + etcd::Client etcd(etcd_uri); + + const int64_t ttl = 3; + const std::string key = "key"; + const std::string meta_str = "meta ...."; + + etcd::Response resp = etcd.leasegrant(ttl).get(); + auto lease_id = resp.value().lease(); + etcd.add(key, meta_str, lease_id); + + std::function handler = + [](std::exception_ptr eptr) { + try { + if (eptr) { + std::rethrow_exception(eptr); + } + } catch (const std::runtime_error& e) { + std::cerr << "Connection failure \"" << e.what() << "\"\n"; + } catch (const std::out_of_range& e) { + std::cerr << "Lease expiry \"" << e.what() << "\"\n"; + } + }; + etcd::KeepAlive keepalive(etcd, handler, ttl, lease_id); + std::this_thread::sleep_for(std::chrono::seconds(5)); +} diff --git a/tst/LockTest.cpp b/tst/LockTest.cpp index 6111393..3e332da 100644 --- a/tst/LockTest.cpp +++ b/tst/LockTest.cpp @@ -10,10 +10,10 @@ #include "etcd/Client.hpp" #include "etcd/KeepAlive.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("lock and unlock") -{ +TEST_CASE("lock and unlock") { etcd::Client etcd(etcd_url); // lock @@ -29,8 +29,7 @@ TEST_CASE("lock and unlock") REQUIRE(0 == resp2.error_code()); } -TEST_CASE("double lock will fail") -{ +TEST_CASE("double lock will fail") { etcd::Client etcd(etcd_url); // lock @@ -42,7 +41,7 @@ TEST_CASE("double lock will fail") bool first_lock_release = false; std::string lock_key = resp1.lock_key(); - auto second_lock_thr = std::thread([&](){ + auto second_lock_thr = std::thread([&]() { // lock again etcd::Response resp2 = etcd.lock("/test/abcd").get(); CHECK("lock" == resp2.action()); @@ -62,7 +61,8 @@ TEST_CASE("double lock will fail") REQUIRE(0 == resp3.error_code()); // create a duration - // using a duration longer than default lease TTL for lock (see: DEFAULT_LEASE_TTL_FOR_LOCK) + // using a duration longer than default lease TTL for lock (see: + // DEFAULT_LEASE_TTL_FOR_LOCK) std::this_thread::sleep_for(std::chrono::seconds(15)); // unlock the first lock @@ -84,8 +84,7 @@ TEST_CASE("double lock will fail") REQUIRE(0 == resp5.error_code()); } -TEST_CASE("lock could be timeout") -{ +TEST_CASE("lock could be timeout") { etcd::Client etcd(etcd_url); // setup the timeout @@ -97,7 +96,7 @@ TEST_CASE("lock could be timeout") REQUIRE(resp1.is_ok()); REQUIRE(0 == resp1.error_code()); - auto lock_in_another_thread = std::thread([&](){ + auto lock_in_another_thread = std::thread([&]() { // lock again etcd::Response resp2 = etcd.lock("/test/abcd").get(); CHECK("lock" == resp2.action()); @@ -113,22 +112,22 @@ TEST_CASE("lock could be timeout") REQUIRE(0 == resp5.error_code()); } -TEST_CASE("lock using lease") -{ +TEST_CASE("lock using lease") { etcd::Client etcd(etcd_url); bool failed = false; - std::function handler = [&failed](std::exception_ptr eptr) { - try { - if (eptr) { + std::function handler = + [&failed](std::exception_ptr eptr) { + try { + if (eptr) { std::rethrow_exception(eptr); + } + } catch (const std::exception& e) { + std::cerr << "Caught exception \"" << e.what() << "\"\n"; + failed = true; } - } catch(const std::exception& e) { - std::cerr << "Caught exception \"" << e.what() << "\"\n"; - failed = true; - } - }; + }; // with handler { @@ -197,25 +196,31 @@ TEST_CASE("lock using lease") } } -TEST_CASE("concurrent lock & unlock") -{ +TEST_CASE("concurrent lock & unlock") { etcd::Client etcd(etcd_url); std::string const lock_key = "/test/test_key"; constexpr size_t trials = 192; - std::function locker = [&etcd](std::string const &key, const size_t index) { - std::cout << "start lock for " << key << ", index is " << index << std::endl; - auto resp = etcd.lock(key).get(); - std::cout << "lock for " << index << " is ok, starts sleeping: ..." << resp.error_message() << std::endl << std::flush; - REQUIRE(resp.is_ok()); - std::srand(index); - size_t time_to_sleep = 1; - std::this_thread::sleep_for(std::chrono::seconds(time_to_sleep)); - std::cout << "lock for " << index << " resumes from sleep: ..." << resp.error_message() << std::endl << std::flush; - REQUIRE(etcd.unlock(resp.lock_key()).get().is_ok()); - std::cout << "thread " << index << " been unlocked" << std::endl << std::flush; - }; + std::function locker = + [&etcd](std::string const& key, const size_t index) { + std::cout << "start lock for " << key << ", index is " << index + << std::endl; + auto resp = etcd.lock(key).get(); + std::cout << "lock for " << index << " is ok, starts sleeping: ..." + << resp.error_message() << std::endl + << std::flush; + REQUIRE(resp.is_ok()); + std::srand(index); + size_t time_to_sleep = 1; + std::this_thread::sleep_for(std::chrono::seconds(time_to_sleep)); + std::cout << "lock for " << index << " resumes from sleep: ..." + << resp.error_message() << std::endl + << std::flush; + REQUIRE(etcd.unlock(resp.lock_key()).get().is_ok()); + std::cout << "thread " << index << " been unlocked" << std::endl + << std::flush; + }; std::vector locks(trials); for (size_t index = 0; index < trials; ++index) { @@ -233,16 +238,19 @@ TEST_CASE("concurrent lock & unlock with a put in between") { constexpr size_t trials = 128; - std::function locker = [&etcd](std::string const &key, const size_t index) { - std::cout << "start lock for " << index << std::endl; - auto resp = etcd.lock(key, true).get(); - std::cout << "lock for " << index << " is ok, start put and unlock: ..." << resp.error_message() << std::endl; - REQUIRE(resp.is_ok()); - auto put_resp = etcd.put("/test/test_put", "hello" + std::to_string(index)).get(); - REQUIRE(put_resp.is_ok()); - REQUIRE(etcd.unlock(resp.lock_key()).get().is_ok()); - std::cout << "thread " << index << " been unlocked" << std::endl; - }; + std::function locker = + [&etcd](std::string const& key, const size_t index) { + std::cout << "start lock for " << index << std::endl; + auto resp = etcd.lock(key, true).get(); + std::cout << "lock for " << index << " is ok, start put and unlock: ..." + << resp.error_message() << std::endl; + REQUIRE(resp.is_ok()); + auto put_resp = + etcd.put("/test/test_put", "hello" + std::to_string(index)).get(); + REQUIRE(put_resp.is_ok()); + REQUIRE(etcd.unlock(resp.lock_key()).get().is_ok()); + std::cout << "thread " << index << " been unlocked" << std::endl; + }; std::vector locks(trials); for (size_t index = 0; index < trials; ++index) { diff --git a/tst/MemLeakTest.cpp b/tst/MemLeakTest.cpp index 05a99dc..b4353dc 100644 --- a/tst/MemLeakTest.cpp +++ b/tst/MemLeakTest.cpp @@ -6,25 +6,22 @@ #include "etcd/Client.hpp" #include "etcd/KeepAlive.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); class DistributedLock { -public: - DistributedLock(const std::string &lock_name, - uint timeout = 0); - ~DistributedLock() noexcept; - inline bool lock_acquired() { - return _acquired; - } + public: + DistributedLock(const std::string& lock_name, uint timeout = 0); + ~DistributedLock() noexcept; + inline bool lock_acquired() { return _acquired; } -private: - bool _acquired = false; - std::string _lock_key; - std::unique_ptr<::etcd::Client> _etcd_client; + private: + bool _acquired = false; + std::string _lock_key; + std::unique_ptr<::etcd::Client> _etcd_client; }; -DistributedLock::DistributedLock(const std::string &lock_name, - uint timeout) { +DistributedLock::DistributedLock(const std::string& lock_name, uint timeout) { _etcd_client = std::unique_ptr(new etcd::Client(etcd_url)); try { @@ -35,12 +32,14 @@ DistributedLock::DistributedLock(const std::string &lock_name, _acquired = true; } } else { - std::future future = std::async(std::launch::async, [&]() { - etcd::Response resp = _etcd_client->lock(lock_name).get(); - return resp; - }); + std::future future = + std::async(std::launch::async, [&]() { + etcd::Response resp = _etcd_client->lock(lock_name).get(); + return resp; + }); - std::future_status status = future.wait_for(std::chrono::seconds(timeout)); + std::future_status status = + future.wait_for(std::chrono::seconds(timeout)); if (status == std::future_status::ready) { auto resp = future.get(); if (resp.is_ok()) { @@ -48,12 +47,13 @@ DistributedLock::DistributedLock(const std::string &lock_name, _acquired = true; } } else if (status == std::future_status::timeout) { - std::cerr << "failed to acquire distributed because of lock timeout" << std::endl; + std::cerr << "failed to acquire distributed because of lock timeout" + << std::endl; } else { std::cerr << "failed to acquire distributed lock" << std::endl; } } - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "failed to construct: " << e.what() << std::endl; } } @@ -68,17 +68,17 @@ DistributedLock::~DistributedLock() noexcept { if (!resp.is_ok()) { std::cout << resp.error_code() << std::endl; } - } catch (std::exception &e) { + } catch (std::exception& e) { std::cerr << "failed to destruct: " << e.what() << std::endl; } } int main() { int i = 0, t = 0; - while(t < 100 /* update this value to make it run for longer */) { + while (t < 100 /* update this value to make it run for longer */) { { DistributedLock lock(std::to_string(i), 0); - if(!lock.lock_acquired()) { + if (!lock.lock_acquired()) { std::cerr << "failed to acquire lock" << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); diff --git a/tst/MemLeakWatcherTest.cpp b/tst/MemLeakWatcherTest.cpp index 3f1f5a6..65b4c82 100644 --- a/tst/MemLeakWatcherTest.cpp +++ b/tst/MemLeakWatcherTest.cpp @@ -8,14 +8,12 @@ #include "etcd/KeepAlive.hpp" #include "etcd/Watcher.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); static std::atomic_int watcher_called; -void print_response(etcd::Response const & resp) -{ - watcher_called.fetch_add(1); -} +void print_response(etcd::Response const& resp) { watcher_called.fetch_add(1); } /** * @brief emulate the behavior of creating watcher many times: @@ -24,7 +22,8 @@ void print_response(etcd::Response const & resp) * 2. change a value * 3. cancel the watcher */ -void watch_once(etcd::Client & client, std::unique_ptr &watcher, const size_t round) { +void watch_once(etcd::Client& client, std::unique_ptr& watcher, + const size_t round) { const std::string my_prefix = "/test"; const std::string my_key = my_prefix + "/foo"; watcher.reset(new etcd::Watcher(client, my_prefix, print_response, true)); @@ -42,19 +41,20 @@ void watch_once(etcd::Client & client, std::unique_ptr &watcher, watcher->Cancel(); } -TEST_CASE("watch shouldn't leak memory") -{ +TEST_CASE("watch shouldn't leak memory") { watcher_called.store(0); // issue some changes to see if the watcher works etcd::Client client(etcd_url); std::unique_ptr watcher; - for (int round = 0; round < 10 /* update this value to make it run for longer */; ++round) { + for (int round = 0; + round < 10 /* update this value to make it run for longer */; ++round) { if (round % 50 == 0) { std::cout << "starting round " << round << std::endl; } watch_once(client, watcher, round); } - std::cout << "watcher been called for " << watcher_called.load() << " times" << std::endl; + std::cout << "watcher been called for " << watcher_called.load() << " times" + << std::endl; } diff --git a/tst/RewatchTest.cpp b/tst/RewatchTest.cpp index a2a7ffb..f8d5cd8 100644 --- a/tst/RewatchTest.cpp +++ b/tst/RewatchTest.cpp @@ -8,27 +8,28 @@ #include "etcd/SyncClient.hpp" #include "etcd/Watcher.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); static int watcher_called = 0; -void print_response(etcd::Response const & resp) -{ +void print_response(etcd::Response const& resp) { ++watcher_called; std::cout << "print response called" << std::endl; if (resp.error_code()) { std::cout << resp.error_code() << ": " << resp.error_message() << std::endl; - } - else { + } else { std::cout << resp.action() << " " << resp.value().as_string() << std::endl; - std::cout << "Previous value: " << resp.prev_value().as_string() << std::endl; + std::cout << "Previous value: " << resp.prev_value().as_string() + << std::endl; std::cout << "Events size: " << resp.events().size() << std::endl; - for (auto const &ev: resp.events()) { - std::cout << "Value change in events: " << static_cast(ev.event_type()) - << ", prev kv = " << ev.prev_kv().key() << " -> " << ev.prev_kv().as_string() - << ", kv = " << ev.kv().key() << " -> " << ev.kv().as_string() - << std::endl; + for (auto const& ev : resp.events()) { + std::cout << "Value change in events: " + << static_cast(ev.event_type()) + << ", prev kv = " << ev.prev_kv().key() << " -> " + << ev.prev_kv().as_string() << ", kv = " << ev.kv().key() + << " -> " << ev.kv().as_string() << std::endl; } } } @@ -48,8 +49,7 @@ void wait_for_connection(std::string endpoints) { } } -void initialize_watcher(const std::string& endpoints, - const std::string& prefix, +void initialize_watcher(const std::string& endpoints, const std::string& prefix, std::function callback, std::shared_ptr& watcher) { // wait until the endpoints turn to be available @@ -64,18 +64,19 @@ void initialize_watcher(const std::string& endpoints, watcher.reset(new etcd::Watcher(client, prefix, callback, true)); // Note that lambda requires `mutable`qualifier. - watcher->Wait([endpoints, prefix, callback, - /* By reference for renewing */ &watcher](bool cancelled) mutable { - if (cancelled) { - std::cout << "watcher's reconnect loop stopped as been cancelled" << std::endl; - return; - } - initialize_watcher(endpoints, prefix, callback, watcher); - }); + watcher->Wait( + [endpoints, prefix, callback, + /* By reference for renewing */ &watcher](bool cancelled) mutable { + if (cancelled) { + std::cout << "watcher's reconnect loop stopped as been cancelled" + << std::endl; + return; + } + initialize_watcher(endpoints, prefix, callback, watcher); + }); } -TEST_CASE("watch should can be re-established") -{ +TEST_CASE("watch should can be re-established") { const std::string my_prefix = "/test"; // the watcher initialized in this way will auto re-connect to etcd @@ -86,8 +87,8 @@ TEST_CASE("watch should can be re-established") for (int round = 0; round < 100000; ++round) { try { etcd::Client client(etcd_url); - auto response = client.set( - my_prefix + "/foo", "bar-" + std::to_string(round)).get(); + auto response = + client.set(my_prefix + "/foo", "bar-" + std::to_string(round)).get(); } catch (...) { // pass } @@ -102,8 +103,8 @@ TEST_CASE("watch should can be re-established") for (int round = 10; round < 20; ++round) { try { etcd::Client client(etcd_url); - auto response = client.set( - my_prefix + "/foo", "bar-" + std::to_string(round)).get(); + auto response = + client.set(my_prefix + "/foo", "bar-" + std::to_string(round)).get(); } catch (...) { // pass } diff --git a/tst/SecurityChannelTest.cpp b/tst/SecurityChannelTest.cpp index 25d7045..f5604c1 100644 --- a/tst/SecurityChannelTest.cpp +++ b/tst/SecurityChannelTest.cpp @@ -9,22 +9,21 @@ static std::string ca = "security-config/certs/ca.crt"; static std::string cert = "security-config/certs/etcd0.example.com.crt"; static std::string key = "security-config/private/etcd0.example.com.key"; -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("https://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("https://127.0.0.1:2379"); -TEST_CASE("setup with auth") -{ - etcd::Client *etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); +TEST_CASE("setup with auth") { + etcd::Client* etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); etcd->rmdir("/test", true).wait(); } -TEST_CASE("add a new key after authenticate") -{ - etcd::Client *etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); +TEST_CASE("add a new key after authenticate") { + etcd::Client* etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); etcd->rmdir("/test", true).wait(); etcd::Response resp = etcd->add("/test/key1", "42").get(); REQUIRE(0 == resp.error_code()); CHECK("create" == resp.action()); - etcd::Value const & val = resp.value(); + etcd::Value const& val = resp.value(); CHECK("42" == val.as_string()); CHECK("/test/key1" == val.key()); CHECK(!val.is_dir()); @@ -32,24 +31,28 @@ TEST_CASE("add a new key after authenticate") CHECK(0 < val.modified_index()); CHECK(1 == val.version()); CHECK(0 < resp.index()); - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "43").get().error_code()); // Key already exists - CHECK(etcd::ERROR_KEY_ALREADY_EXISTS == etcd->add("/test/key1", "42").get().error_code()); // Key already exists - CHECK("etcd-cpp-apiv3: key already exists" == etcd->add("/test/key1", "42").get().error_message()); + CHECK( + etcd::ERROR_KEY_ALREADY_EXISTS == + etcd->add("/test/key1", "43").get().error_code()); // Key already exists + CHECK( + etcd::ERROR_KEY_ALREADY_EXISTS == + etcd->add("/test/key1", "42").get().error_code()); // Key already exists + CHECK("etcd-cpp-apiv3: key already exists" == + etcd->add("/test/key1", "42").get().error_message()); } -TEST_CASE("read a value from etcd") -{ - etcd::Client *etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); +TEST_CASE("read a value from etcd") { + etcd::Client* etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); etcd::Response resp = etcd->get("/test/key1").get(); CHECK("get" == resp.action()); REQUIRE(resp.is_ok()); REQUIRE(0 == resp.error_code()); CHECK("42" == resp.value().as_string()); - CHECK("" == etcd->get("/test").get().value().as_string()); // key points to a directory + CHECK("" == etcd->get("/test").get().value().as_string()); // key points to a + // directory } -TEST_CASE("cleanup") -{ - etcd::Client *etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); +TEST_CASE("cleanup") { + etcd::Client* etcd = etcd::Client::WithSSL(etcd_url, ca, cert, key); REQUIRE(0 == etcd->rmdir("/test", true).get().error_code()); } diff --git a/tst/TransactionTest.cpp b/tst/TransactionTest.cpp index 4a1af0c..942a699 100644 --- a/tst/TransactionTest.cpp +++ b/tst/TransactionTest.cpp @@ -8,16 +8,15 @@ #include "etcd/Client.hpp" #include "etcd/v3/Transaction.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); -TEST_CASE("setup") -{ +TEST_CASE("setup") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); } -TEST_CASE("add a new key") -{ +TEST_CASE("add a new key") { etcd::Client etcd(etcd_url); etcd.rmdir("/test", true).wait(); @@ -49,13 +48,15 @@ TEST_CASE("add a new key") // do some put and delete using txn { etcdv3::Transaction txn; - + // setup the conditions txn.reset_key("/test/x1"); - txn.init_compare("1", etcdv3::CompareResult::EQUAL, etcdv3::CompareTarget::VALUE); + txn.init_compare("1", etcdv3::CompareResult::EQUAL, + etcdv3::CompareTarget::VALUE); txn.reset_key("/test/x2"); - txn.init_compare("2", etcdv3::CompareResult::EQUAL, etcdv3::CompareTarget::VALUE); + txn.init_compare("2", etcdv3::CompareResult::EQUAL, + etcdv3::CompareTarget::VALUE); txn.setup_put("/test/x1", "111"); txn.setup_delete("/test/x2"); @@ -83,8 +84,7 @@ TEST_CASE("add a new key") } } -TEST_CASE("cleanup") -{ +TEST_CASE("cleanup") { etcd::Client etcd(etcd_url); REQUIRE(0 == etcd.rmdir("/test", true).get().error_code()); } diff --git a/tst/WatcherTest.cpp b/tst/WatcherTest.cpp index a5b815c..c5fe100 100644 --- a/tst/WatcherTest.cpp +++ b/tst/WatcherTest.cpp @@ -4,41 +4,42 @@ #include #include -#include "etcd/Watcher.hpp" #include "etcd/SyncClient.hpp" +#include "etcd/Watcher.hpp" -static const std::string etcd_url = etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); +static const std::string etcd_url = + etcdv3::detail::resolve_etcd_endpoints("http://127.0.0.1:2379"); static int watcher_called = 0; -void printResponse(etcd::Response const & resp) -{ +void printResponse(etcd::Response const& resp) { if (resp.error_code()) { - std::cout << "Watcher "<< resp.watch_id() - << " fails with " << resp.error_code() << ": " << resp.error_message() << std::endl; - } - else { - std::cout << "Watcher " << resp.watch_id() - << " responses with " << resp.action() << " " << resp.value().as_string() << std::endl; - std::cout << "Previous value: " << resp.prev_value().as_string() << std::endl; + std::cout << "Watcher " << resp.watch_id() << " fails with " + << resp.error_code() << ": " << resp.error_message() << std::endl; + } else { + std::cout << "Watcher " << resp.watch_id() << " responses with " + << resp.action() << " " << resp.value().as_string() << std::endl; + std::cout << "Previous value: " << resp.prev_value().as_string() + << std::endl; std::cout << "Events size: " << resp.events().size() << std::endl; - for (auto const &ev: resp.events()) { - if (ev.prev_kv().key().find("/leader") == 0 || ev.kv().key().find("/leader") == 0) { + for (auto const& ev : resp.events()) { + if (ev.prev_kv().key().find("/leader") == 0 || + ev.kv().key().find("/leader") == 0) { return; } - std::cout << "Value change in events: " << static_cast(ev.event_type()) - << ", prev kv = " << ev.prev_kv().key() << " -> " << ev.prev_kv().as_string() - << ", kv = " << ev.kv().key() << " -> " << ev.kv().as_string() - << std::endl; + std::cout << "Value change in events: " + << static_cast(ev.event_type()) + << ", prev kv = " << ev.prev_kv().key() << " -> " + << ev.prev_kv().as_string() << ", kv = " << ev.kv().key() + << " -> " << ev.kv().as_string() << std::endl; } } std::cout << "print response called" << std::endl; ++watcher_called; } -TEST_CASE("create watcher") -{ +TEST_CASE("create watcher") { etcd::SyncClient etcd(etcd_url); etcd.rmdir("/test", true); @@ -55,8 +56,7 @@ TEST_CASE("create watcher") etcd.rmdir("/test", true); } -TEST_CASE("watch with correct prefix") -{ +TEST_CASE("watch with correct prefix") { etcd::SyncClient etcd(etcd_url); etcd.rmdir("/test", true); @@ -92,8 +92,7 @@ TEST_CASE("watch with correct prefix") etcd.rmdir("/test", true); } -TEST_CASE("create watcher with cancel") -{ +TEST_CASE("create watcher with cancel") { etcd::SyncClient etcd(etcd_url); etcd.rmdir("/test", true); @@ -115,8 +114,7 @@ TEST_CASE("create watcher with cancel") etcd.rmdir("/test", true); } -TEST_CASE("create watcher on ranges with cancel") -{ +TEST_CASE("create watcher on ranges with cancel") { etcd::SyncClient etcd(etcd_url); etcd.rmdir("/test", true); @@ -138,29 +136,24 @@ TEST_CASE("create watcher on ranges with cancel") etcd.rmdir("/test", true); } -TEST_CASE("watch should exit normally") -{ +TEST_CASE("watch should exit normally") { // cancel immediately after start watch. etcd::Watcher watcher(etcd_url, "/test", printResponse, true); watcher.Cancel(); } -TEST_CASE("watch should can be cancelled repeatedly") -{ +TEST_CASE("watch should can be cancelled repeatedly") { etcd::Watcher watcher(etcd_url, "/test", printResponse, true); std::vector threads(10); for (size_t i = 0; i < 10; ++i) { - threads[i] = std::thread([&]() { - watcher.Cancel(); - }); + threads[i] = std::thread([&]() { watcher.Cancel(); }); } for (size_t i = 0; i < 10; ++i) { threads[i].join(); } } -TEST_CASE("watch changes on the same key (#212)") -{ +TEST_CASE("watch changes on the same key (#212)") { std::string key_watch = "key watch"; etcd::SyncClient client(etcd_url); client.put(key_watch, "inittt"); @@ -168,33 +161,30 @@ TEST_CASE("watch changes on the same key (#212)") auto current_index = client.head().index(); std::cout << "Current index " << current_index << std::endl; auto internal_cb = [&](etcd::Response resp) -> void { - if (!resp.is_ok()) { - std::cout << "Error: " << resp.error_message() << std::endl; - return; - } - for (auto const &event: resp.events()) { - std::cout << "Watch '" << event.kv().key() - << "'. ModifedRevision : " << event.kv().modified_index() - << "', Vision : " << event.kv().version() - << ", value = " << event.kv().as_string() << std::endl; - } + if (!resp.is_ok()) { + std::cout << "Error: " << resp.error_message() << std::endl; + return; + } + for (auto const& event : resp.events()) { + std::cout << "Watch '" << event.kv().key() + << "'. ModifedRevision : " << event.kv().modified_index() + << "', Vision : " << event.kv().version() + << ", value = " << event.kv().as_string() << std::endl; + } }; - auto wait_cb = [&](bool) {}; - etcd::Watcher w(client, key_watch, current_index, - std::move(internal_cb), - std::move(wait_cb), - false); + auto wait_cb = [&](bool) {}; + etcd::Watcher w(client, key_watch, current_index, std::move(internal_cb), + std::move(wait_cb), false); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - for (int i = 0; i < 10; ) { - std::string value = "watch_" + std::to_string(i++); + for (int i = 0; i < 10; ++i) { + std::string value = "watch_" + std::to_string(i); client.put(key_watch, value); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } -TEST_CASE("create two watcher") -{ +TEST_CASE("create two watcher") { etcd::Watcher w1(etcd_url, "/test", printResponse, true); etcd::Watcher w2(etcd_url, "/test", printResponse, true);