From b9eaa03c8f85cdd23145fdbf8cb09dd4c9184211 Mon Sep 17 00:00:00 2001 From: Tao He Date: Wed, 18 Mar 2020 17:49:55 +0800 Subject: [PATCH] Re-org v3 related files to make it a submodule. --- CMakeLists.txt | 34 +++-- cmake/FindGRPC.cmake | 143 ++++++++++++++++++ etcd/Client.hpp | 6 +- etcd/Response.hpp | 12 +- {v3/include => etcd/v3}/Action.hpp | 5 +- .../v3}/AsyncCompareAndDeleteAction.hpp | 4 +- .../v3}/AsyncCompareAndSwapAction.hpp | 4 +- {v3/include => etcd/v3}/AsyncDeleteAction.hpp | 4 +- .../v3}/AsyncDeleteRangeResponse.hpp | 4 +- {v3/include => etcd/v3}/AsyncGetAction.hpp | 4 +- .../v3}/AsyncLeaseGrantAction.hpp | 4 +- .../v3}/AsyncLeaseGrantResponse.hpp | 2 +- {v3/include => etcd/v3}/AsyncLockAction.hpp | 4 +- {v3/include => etcd/v3}/AsyncLockResponse.hpp | 2 +- .../v3}/AsyncRangeResponse.hpp | 2 +- {v3/include => etcd/v3}/AsyncSetAction.hpp | 4 +- {v3/include => etcd/v3}/AsyncTxnAction.hpp | 6 +- {v3/include => etcd/v3}/AsyncTxnResponse.hpp | 2 +- {v3/include => etcd/v3}/AsyncUpdateAction.hpp | 4 +- {v3/include => etcd/v3}/AsyncWatchAction.hpp | 4 +- .../v3}/AsyncWatchResponse.hpp | 2 +- {v3/include => etcd/v3}/KeyValue.hpp | 0 {v3/include => etcd/v3}/Transaction.hpp | 0 {v3/include => etcd/v3}/V3Response.hpp | 2 +- {v3/include => etcd/v3}/action_constants.hpp | 0 src/CMakeLists.txt | 16 +- src/Client.cpp | 99 ++++++++---- src/Response.cpp | 13 +- src/Value.cpp | 2 +- src/Watcher.cpp | 2 +- {v3/src => src/v3}/Action.cpp | 6 +- .../v3}/AsyncCompareAndDeleteAction.cpp | 6 +- .../v3}/AsyncCompareAndSwapAction.cpp | 6 +- {v3/src => src/v3}/AsyncDeleteAction.cpp | 4 +- .../v3}/AsyncDeleteRangeResponse.cpp | 4 +- {v3/src => src/v3}/AsyncGetAction.cpp | 4 +- {v3/src => src/v3}/AsyncLeaseGrantAction.cpp | 6 +- .../v3}/AsyncLeaseGrantResponse.cpp | 4 +- {v3/src => src/v3}/AsyncLockAction.cpp | 4 +- {v3/src => src/v3}/AsyncLockResponse.cpp | 4 +- {v3/src => src/v3}/AsyncRangeResponse.cpp | 4 +- {v3/src => src/v3}/AsyncSetAction.cpp | 6 +- {v3/src => src/v3}/AsyncTxnAction.cpp | 6 +- {v3/src => src/v3}/AsyncTxnResponse.cpp | 8 +- {v3/src => src/v3}/AsyncUpdateAction.cpp | 8 +- {v3/src => src/v3}/AsyncWatchAction.cpp | 41 +++-- {v3/src => src/v3}/AsyncWatchResponse.cpp | 6 +- {v3/src => src/v3}/KeyValue.cpp | 2 +- {v3/src => src/v3}/Transaction.cpp | 2 +- {v3/src => src/v3}/V3Response.cpp | 4 +- {v3/src => src/v3}/action_constants.cpp | 3 +- 51 files changed, 375 insertions(+), 153 deletions(-) create mode 100644 cmake/FindGRPC.cmake rename {v3/include => etcd/v3}/Action.hpp (86%) rename {v3/include => etcd/v3}/AsyncCompareAndDeleteAction.hpp (88%) rename {v3/include => etcd/v3}/AsyncCompareAndSwapAction.hpp (88%) rename {v3/include => etcd/v3}/AsyncDeleteAction.hpp (86%) rename {v3/include => etcd/v3}/AsyncDeleteRangeResponse.hpp (86%) rename {v3/include => etcd/v3}/AsyncGetAction.hpp (86%) rename {v3/include => etcd/v3}/AsyncLeaseGrantAction.hpp (87%) rename {v3/include => etcd/v3}/AsyncLeaseGrantResponse.hpp (91%) rename {v3/include => etcd/v3}/AsyncLockAction.hpp (92%) rename {v3/include => etcd/v3}/AsyncLockResponse.hpp (94%) rename {v3/include => etcd/v3}/AsyncRangeResponse.hpp (91%) rename {v3/include => etcd/v3}/AsyncSetAction.hpp (88%) rename {v3/include => etcd/v3}/AsyncTxnAction.hpp (83%) rename {v3/include => etcd/v3}/AsyncTxnResponse.hpp (91%) rename {v3/include => etcd/v3}/AsyncUpdateAction.hpp (87%) rename {v3/include => etcd/v3}/AsyncWatchAction.hpp (91%) rename {v3/include => etcd/v3}/AsyncWatchResponse.hpp (91%) rename {v3/include => etcd/v3}/KeyValue.hpp (100%) rename {v3/include => etcd/v3}/Transaction.hpp (100%) rename {v3/include => etcd/v3}/V3Response.hpp (97%) rename {v3/include => etcd/v3}/action_constants.hpp (100%) rename {v3/src => src/v3}/Action.cpp (68%) rename {v3/src => src/v3}/AsyncCompareAndDeleteAction.cpp (92%) rename {v3/src => src/v3}/AsyncCompareAndSwapAction.cpp (93%) rename {v3/src => src/v3}/AsyncDeleteAction.cpp (91%) rename {v3/src => src/v3}/AsyncDeleteRangeResponse.cpp (87%) rename {v3/src => src/v3}/AsyncGetAction.cpp (92%) rename {v3/src => src/v3}/AsyncLeaseGrantAction.cpp (85%) rename {v3/src => src/v3}/AsyncLeaseGrantResponse.cpp (69%) rename {v3/src => src/v3}/AsyncLockAction.cpp (94%) rename {v3/src => src/v3}/AsyncLockResponse.cpp (73%) rename {v3/src => src/v3}/AsyncRangeResponse.cpp (85%) rename {v3/src => src/v3}/AsyncSetAction.cpp (92%) rename {v3/src => src/v3}/AsyncTxnAction.cpp (88%) rename {v3/src => src/v3}/AsyncTxnResponse.cpp (88%) rename {v3/src => src/v3}/AsyncUpdateAction.cpp (88%) rename {v3/src => src/v3}/AsyncWatchAction.cpp (69%) rename {v3/src => src/v3}/AsyncWatchResponse.cpp (78%) rename {v3/src => src/v3}/KeyValue.cpp (82%) rename {v3/src => src/v3}/Transaction.cpp (99%) rename {v3/src => src/v3}/V3Response.cpp (94%) rename {v3/src => src/v3}/action_constants.cpp (91%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e584331..7d6c78a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,23 +13,22 @@ find_package(Boost REQUIRED COMPONENTS system thread locale random) find_package(OpenSSL REQUIRED) find_package(Protobuf REQUIRED) -set(GRPC_LIBRARY_PATH /usr/lib - /usr/lib64 - /usr/local/lib - /usr/local/lib64 - /usr/local/opt/grpc) -find_library(GPR_LIBRARY NAMES gpr PATHS ${GRPC_LIBRARY_PATH}) -find_library(GRPC_LIBRARY NAMES grpc PATHS ${GRPC_LIBRARY_PATH}) -find_library(GRPC++_LIBRARY NAMES grpc++ PATHS ${GRPC_LIBRARY_PATH}) -set(GRPC_LIBRARIES ${GPR_LIBRARY} ${GRPC_LIBRARY} ${GRPC++_LIBRARY}) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindGRPC.cmake) +set(GRPC_LIBRARIES ${GPR_LIBRARY} ${GRPC_LIBRARY} ${GRPC_GRPC++_LIBRARY}) -file(GLOB_RECURSE PROTO_SRC RELATIVE "${CMAKE_SOURCE_DIR}/proto" "proto/*.proto") +file(GLOB_RECURSE PROTO_SRC RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/proto" "proto/*.proto") -add_custom_target(proto-gen - COMMAND protoc -I . --cpp_out=. ${PROTO_SRC} - COMMAND protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ./rpc.proto ./v3lock.proto - COMMENT "Generate protobuf stuffs" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/proto) +# Generate protobuf definitions +execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} + -I ${CMAKE_CURRENT_SOURCE_DIR}/proto + --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto + ${PROTO_SRC}) +execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} + -I ${CMAKE_CURRENT_SOURCE_DIR}/proto + --grpc_out=${CMAKE_CURRENT_SOURCE_DIR}/proto + --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} + ${CMAKE_CURRENT_SOURCE_DIR}/proto/rpc.proto + ${CMAKE_CURRENT_SOURCE_DIR}/proto/v3lock.proto) enable_testing() include_directories(SYSTEM ${CPPREST_INCLUDE_DIR} @@ -40,4 +39,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-string-compare -std=c++11") add_subdirectory(src) -add_subdirectory(tst) + +if (BUILD_TESTS) + add_subdirectory(tst) +endif () diff --git a/cmake/FindGRPC.cmake b/cmake/FindGRPC.cmake new file mode 100644 index 0000000..ee2c6dc --- /dev/null +++ b/cmake/FindGRPC.cmake @@ -0,0 +1,143 @@ +# This file is taken from +# +# https://github.com/IvanSafonov/grpc-cmake-example +# +# The original repository is open-sourced with the MIT license. +# +# +# Locate and configure the gRPC library +# +# Adds the following targets: +# +# gRPC::gpr - GPR library +# gRPC::grpc - gRPC library +# gRPC::grpc++ - gRPC C++ library +# gRPC::grpc++_reflection - gRPC C++ reflection library +# gRPC::grpc_cpp_plugin - C++ generator plugin for Protocol Buffers +# + +# +# Generates C++ sources from the .proto files +# +# grpc_generate_cpp ( [...]) +# +# SRCS - variable to define with autogenerated source files +# HDRS - variable to define with autogenerated header files +# DEST - directory where the source files will be created +# ARGN - .proto files +# +function(GRPC_GENERATE_CPP SRCS HDRS DEST) + if(NOT ARGN) + message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files") + return() + endif() + + if(GRPC_GENERATE_CPP_APPEND_PATH) + # Create an include path for each file specified + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(ABS_PATH ${ABS_FIL} PATH) + list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + else() + set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + if(DEFINED PROTOBUF_IMPORT_DIRS) + foreach(DIR ${PROTOBUF_IMPORT_DIRS}) + get_filename_component(ABS_PATH ${DIR} ABSOLUTE) + list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + endif() + + set(${SRCS}) + set(${HDRS}) + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + + list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc") + list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h") + + add_custom_command( + OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc" + "${DEST}/${FIL_WE}.grpc.pb.h" + COMMAND protobuf::protoc + ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL} + DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin + COMMENT "Running C++ gRPC compiler on ${FIL}" + VERBATIM ) + endforeach() + + set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} PARENT_SCOPE) + set(${HDRS} ${${HDRS}} PARENT_SCOPE) +endfunction() + +# By default have GRPC_GENERATE_CPP macro pass -I to protoc +# for each directory where a proto file is referenced. +if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH) + set(GRPC_GENERATE_CPP_APPEND_PATH TRUE) +endif() + +# Find gRPC include directory +find_path(GRPC_INCLUDE_DIR grpc/grpc.h) +mark_as_advanced(GRPC_INCLUDE_DIR) + +# Find gGPR library +find_library(GPR_LIBRARY NAMES gpr) +mark_as_advanced(GRPC_GPR_LIBRARY) +add_library(gRPC::gpr UNKNOWN IMPORTED) +set_target_properties(gRPC::gpr PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES "-lpthread;-ldl" + IMPORTED_LOCATION ${GPR_LIBRARY} +) + +# Find gRPC library +find_library(GRPC_LIBRARY NAMES grpc) +mark_as_advanced(GRPC_LIBRARY) +add_library(gRPC::grpc UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES gRPC::gpr + IMPORTED_LOCATION ${GRPC_LIBRARY} +) + +# Find gRPC C++ library +find_library(GRPC_GRPC++_LIBRARY NAMES grpc++) +mark_as_advanced(GRPC_GRPC++_LIBRARY) +add_library(gRPC::grpc++ UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc++ PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES gRPC::grpc + IMPORTED_LOCATION ${GRPC_GRPC++_LIBRARY} +) + +# Find gRPC C++ reflection library +find_library(GRPC_GRPC++_REFLECTION_LIBRARY NAMES grpc++_reflection) +mark_as_advanced(GRPC_GRPC++_REFLECTION_LIBRARY) +add_library(gRPC::grpc++_reflection UNKNOWN IMPORTED) +set_target_properties(gRPC::grpc++_reflection PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${GRPC_INCLUDE_DIR} + INTERFACE_LINK_LIBRARIES gRPC::grpc++ + IMPORTED_LOCATION ${GRPC_GRPC++_REFLECTION_LIBRARY} +) + +# Find gRPC CPP generator +find_program(GRPC_CPP_PLUGIN NAMES grpc_cpp_plugin) +mark_as_advanced(GRPC_CPP_PLUGIN) +add_executable(gRPC::grpc_cpp_plugin IMPORTED) +set_target_properties(gRPC::grpc_cpp_plugin PROPERTIES + IMPORTED_LOCATION ${GRPC_CPP_PLUGIN} +) + +include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(gRPC DEFAULT_MSG + GPR_LIBRARY GRPC_LIBRARY GRPC_INCLUDE_DIR GRPC_GRPC++_REFLECTION_LIBRARY GRPC_CPP_PLUGIN) diff --git a/etcd/Client.hpp b/etcd/Client.hpp index 63792be..3ea756e 100644 --- a/etcd/Client.hpp +++ b/etcd/Client.hpp @@ -29,9 +29,11 @@ namespace etcd 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:4001" + * @param etcd_url is the url of the etcd server to connect to, like "http://127.0.0.1:4001", + * or multiple url, seperated 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); + Client(std::string const & etcd_url, std::string const & load_balancer = "round_robin"); /** * Sends a get request to the etcd server diff --git a/etcd/Response.hpp b/etcd/Response.hpp index 70e35b8..c9baff0 100644 --- a/etcd/Response.hpp +++ b/etcd/Response.hpp @@ -36,7 +36,9 @@ namespace etcd auto v3resp = call->ParseResponse(); - resp = etcd::Response(v3resp); + auto duration = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - call->startTimepoint()); + resp = etcd::Response(v3resp, duration); return resp; }); @@ -109,8 +111,13 @@ namespace etcd */ std::vector const & events() const; + /** + * Returns the duration of request execution in microseconds. + */ + std::chrono::microseconds const & duration() const; + protected: - Response(const etcdv3::V3Response& response); + Response(const etcdv3::V3Response& response, std::chrono::microseconds const& duration); Response(int error_code, char const * error_message); int _error_code; @@ -123,6 +130,7 @@ namespace etcd Keys _keys; std::string _lock_key; // for lock std::vector _events; // for watch + std::chrono::microseconds _duration; // execute duration (in microseconds), during the action created and response parsed friend class SyncClient; friend class etcdv3::AsyncWatchAction; friend class Client; diff --git a/v3/include/Action.hpp b/etcd/v3/Action.hpp similarity index 86% rename from v3/include/Action.hpp rename to etcd/v3/Action.hpp index 949c4f0..6b7e14e 100644 --- a/v3/include/Action.hpp +++ b/etcd/v3/Action.hpp @@ -1,6 +1,8 @@ #ifndef __V3_ACTION_HPP__ #define __V3_ACTION_HPP__ +#include + #include #include "proto/rpc.grpc.pb.h" #include "proto/v3lock.grpc.pb.h" @@ -45,12 +47,13 @@ namespace etcdv3 Action(etcdv3::ActionParameters params); 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; }; } #endif diff --git a/v3/include/AsyncCompareAndDeleteAction.hpp b/etcd/v3/AsyncCompareAndDeleteAction.hpp similarity index 88% rename from v3/include/AsyncCompareAndDeleteAction.hpp rename to etcd/v3/AsyncCompareAndDeleteAction.hpp index 9446a9c..fd9ae88 100644 --- a/v3/include/AsyncCompareAndDeleteAction.hpp +++ b/etcd/v3/AsyncCompareAndDeleteAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncCompareAndSwapAction.hpp b/etcd/v3/AsyncCompareAndSwapAction.hpp similarity index 88% rename from v3/include/AsyncCompareAndSwapAction.hpp rename to etcd/v3/AsyncCompareAndSwapAction.hpp index c1bc240..60a86e3 100644 --- a/v3/include/AsyncCompareAndSwapAction.hpp +++ b/etcd/v3/AsyncCompareAndSwapAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncDeleteAction.hpp b/etcd/v3/AsyncDeleteAction.hpp similarity index 86% rename from v3/include/AsyncDeleteAction.hpp rename to etcd/v3/AsyncDeleteAction.hpp index 06339ff..dd49301 100644 --- a/v3/include/AsyncDeleteAction.hpp +++ b/etcd/v3/AsyncDeleteAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncDeleteRangeResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncDeleteRangeResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncDeleteRangeResponse.hpp b/etcd/v3/AsyncDeleteRangeResponse.hpp similarity index 86% rename from v3/include/AsyncDeleteRangeResponse.hpp rename to etcd/v3/AsyncDeleteRangeResponse.hpp index 3726439..2b37c52 100644 --- a/v3/include/AsyncDeleteRangeResponse.hpp +++ b/etcd/v3/AsyncDeleteRangeResponse.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/V3Response.hpp" -#include "v3/include/Action.hpp" +#include "etcd/v3/V3Response.hpp" +#include "etcd/v3/Action.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncGetAction.hpp b/etcd/v3/AsyncGetAction.hpp similarity index 86% rename from v3/include/AsyncGetAction.hpp rename to etcd/v3/AsyncGetAction.hpp index a1f1905..bffde8e 100644 --- a/v3/include/AsyncGetAction.hpp +++ b/etcd/v3/AsyncGetAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncRangeResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncRangeResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncLeaseGrantAction.hpp b/etcd/v3/AsyncLeaseGrantAction.hpp similarity index 87% rename from v3/include/AsyncLeaseGrantAction.hpp rename to etcd/v3/AsyncLeaseGrantAction.hpp index 892f48c..8675521 100644 --- a/v3/include/AsyncLeaseGrantAction.hpp +++ b/etcd/v3/AsyncLeaseGrantAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncLeaseGrantResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncLeaseGrantResponse.hpp" using grpc::ClientAsyncResponseReader; using etcdserverpb::LeaseGrantResponse; diff --git a/v3/include/AsyncLeaseGrantResponse.hpp b/etcd/v3/AsyncLeaseGrantResponse.hpp similarity index 91% rename from v3/include/AsyncLeaseGrantResponse.hpp rename to etcd/v3/AsyncLeaseGrantResponse.hpp index 3855c9b..e7bdded 100644 --- a/v3/include/AsyncLeaseGrantResponse.hpp +++ b/etcd/v3/AsyncLeaseGrantResponse.hpp @@ -3,7 +3,7 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/V3Response.hpp" +#include "etcd/v3/V3Response.hpp" using etcdserverpb::LeaseGrantResponse; diff --git a/v3/include/AsyncLockAction.hpp b/etcd/v3/AsyncLockAction.hpp similarity index 92% rename from v3/include/AsyncLockAction.hpp rename to etcd/v3/AsyncLockAction.hpp index 1508c15..5390014 100644 --- a/v3/include/AsyncLockAction.hpp +++ b/etcd/v3/AsyncLockAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/v3lock.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncLockResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncLockResponse.hpp" #include "etcd/Response.hpp" diff --git a/v3/include/AsyncLockResponse.hpp b/etcd/v3/AsyncLockResponse.hpp similarity index 94% rename from v3/include/AsyncLockResponse.hpp rename to etcd/v3/AsyncLockResponse.hpp index 15186a9..2d8c032 100644 --- a/v3/include/AsyncLockResponse.hpp +++ b/etcd/v3/AsyncLockResponse.hpp @@ -3,7 +3,7 @@ #include #include "proto/v3lock.grpc.pb.h" -#include "v3/include/V3Response.hpp" +#include "etcd/v3/V3Response.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncRangeResponse.hpp b/etcd/v3/AsyncRangeResponse.hpp similarity index 91% rename from v3/include/AsyncRangeResponse.hpp rename to etcd/v3/AsyncRangeResponse.hpp index 3619671..1eb4122 100644 --- a/v3/include/AsyncRangeResponse.hpp +++ b/etcd/v3/AsyncRangeResponse.hpp @@ -3,7 +3,7 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/V3Response.hpp" +#include "etcd/v3/V3Response.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncSetAction.hpp b/etcd/v3/AsyncSetAction.hpp similarity index 88% rename from v3/include/AsyncSetAction.hpp rename to etcd/v3/AsyncSetAction.hpp index 4f4d437..e025408 100644 --- a/v3/include/AsyncSetAction.hpp +++ b/etcd/v3/AsyncSetAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncTxnAction.hpp b/etcd/v3/AsyncTxnAction.hpp similarity index 83% rename from v3/include/AsyncTxnAction.hpp rename to etcd/v3/AsyncTxnAction.hpp index 8d15c95..e6b819f 100644 --- a/v3/include/AsyncTxnAction.hpp +++ b/etcd/v3/AsyncTxnAction.hpp @@ -3,9 +3,9 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" +#include "etcd/v3/Transaction.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncTxnResponse.hpp b/etcd/v3/AsyncTxnResponse.hpp similarity index 91% rename from v3/include/AsyncTxnResponse.hpp rename to etcd/v3/AsyncTxnResponse.hpp index d1e0d98..7f65319 100644 --- a/v3/include/AsyncTxnResponse.hpp +++ b/etcd/v3/AsyncTxnResponse.hpp @@ -1,8 +1,8 @@ #ifndef __ASYNC_TXNRESPONSE_HPP__ #define __ASYNC_TXNRESPONSE_HPP__ -#include "v3/include/V3Response.hpp" #include "proto/rpc.pb.h" +#include "etcd/v3/V3Response.hpp" using etcdserverpb::TxnResponse; diff --git a/v3/include/AsyncUpdateAction.hpp b/etcd/v3/AsyncUpdateAction.hpp similarity index 87% rename from v3/include/AsyncUpdateAction.hpp rename to etcd/v3/AsyncUpdateAction.hpp index 97d17fc..dc62e0e 100644 --- a/v3/include/AsyncUpdateAction.hpp +++ b/etcd/v3/AsyncUpdateAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" using grpc::ClientAsyncResponseReader; diff --git a/v3/include/AsyncWatchAction.hpp b/etcd/v3/AsyncWatchAction.hpp similarity index 91% rename from v3/include/AsyncWatchAction.hpp rename to etcd/v3/AsyncWatchAction.hpp index 4e13ac7..3453e87 100644 --- a/v3/include/AsyncWatchAction.hpp +++ b/etcd/v3/AsyncWatchAction.hpp @@ -3,8 +3,8 @@ #include #include "proto/rpc.grpc.pb.h" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncWatchResponse.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncWatchResponse.hpp" #include "etcd/Response.hpp" diff --git a/v3/include/AsyncWatchResponse.hpp b/etcd/v3/AsyncWatchResponse.hpp similarity index 91% rename from v3/include/AsyncWatchResponse.hpp rename to etcd/v3/AsyncWatchResponse.hpp index 32a2a71..5ce6b57 100644 --- a/v3/include/AsyncWatchResponse.hpp +++ b/etcd/v3/AsyncWatchResponse.hpp @@ -4,7 +4,7 @@ #include #include "proto/rpc.grpc.pb.h" #include "proto/rpc.pb.h" -#include "v3/include/V3Response.hpp" +#include "etcd/v3/V3Response.hpp" using etcdserverpb::WatchRequest; diff --git a/v3/include/KeyValue.hpp b/etcd/v3/KeyValue.hpp similarity index 100% rename from v3/include/KeyValue.hpp rename to etcd/v3/KeyValue.hpp diff --git a/v3/include/Transaction.hpp b/etcd/v3/Transaction.hpp similarity index 100% rename from v3/include/Transaction.hpp rename to etcd/v3/Transaction.hpp diff --git a/v3/include/V3Response.hpp b/etcd/v3/V3Response.hpp similarity index 97% rename from v3/include/V3Response.hpp rename to etcd/v3/V3Response.hpp index a82351f..0c97789 100644 --- a/v3/include/V3Response.hpp +++ b/etcd/v3/V3Response.hpp @@ -4,7 +4,7 @@ #include #include "proto/kv.pb.h" -#include "v3/include/KeyValue.hpp" +#include "etcd/v3/KeyValue.hpp" namespace etcdv3 { diff --git a/v3/include/action_constants.hpp b/etcd/v3/action_constants.hpp similarity index 100% rename from v3/include/action_constants.hpp rename to etcd/v3/action_constants.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d27cd6c..ec8b914 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,11 +1,12 @@ -file(GLOB_RECURSE CPP_CLIENT_SRC RELATIVE "${CMAKE_SOURCE_DIR}/src" - "${CMAKE_SOURCE_DIR}/proto/*.cc" - "${CMAKE_SOURCE_DIR}/src/*.cpp" - "${CMAKE_SOURCE_DIR}/v3/src/*.cpp") +file(GLOB_RECURSE CPP_CLIENT_SRC + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/**/*.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/../proto/*.cc") add_library(etcd-cpp-api SHARED ${CPP_CLIENT_SRC}) set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11) -target_include_directories(etcd-cpp-api PRIVATE ${CMAKE_SOURCE_DIR}/proto) +target_include_directories(etcd-cpp-api PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../proto) target_link_libraries(etcd-cpp-api PUBLIC ${CPPREST_LIB} @@ -28,11 +29,10 @@ install (FILES ../proto/auth.pb.h ../proto/v3lock.pb.h ../proto/v3lock.grpc.pb.h DESTINATION include/etcd/proto) -install (FILES ../v3/include/Transaction.hpp - DESTINATION include/etcd/v3/include) +install (FILES ../etcd/v3/Transaction.hpp + DESTINATION include/etcd/v3) install (FILES ../proto/gogoproto/gogo.pb.h DESTINATION include/etcd/proto/gogoproto) install (FILES ../proto/google/api/annotations.pb.h ../proto/google/api/http.pb.h DESTINATION include/etcd/proto/google/api) - diff --git a/src/Client.cpp b/src/Client.cpp index 1e0ef70..c3cf93b 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1,42 +1,85 @@ +#include +#include +#include +#include +#include + #include #include "etcd/Client.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Action.hpp" -#include "v3/include/AsyncTxnResponse.hpp" -#include "v3/include/AsyncRangeResponse.hpp" -#include "v3/include/AsyncWatchResponse.hpp" -#include "v3/include/AsyncDeleteRangeResponse.hpp" -#include "v3/include/AsyncLockResponse.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Action.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" +#include "etcd/v3/AsyncRangeResponse.hpp" +#include "etcd/v3/AsyncWatchResponse.hpp" +#include "etcd/v3/AsyncDeleteRangeResponse.hpp" +#include "etcd/v3/AsyncLockResponse.hpp" +#include "etcd/v3/Transaction.hpp" #include -#include "v3/include/AsyncSetAction.hpp" -#include "v3/include/AsyncCompareAndSwapAction.hpp" -#include "v3/include/AsyncCompareAndDeleteAction.hpp" -#include "v3/include/AsyncUpdateAction.hpp" -#include "v3/include/AsyncGetAction.hpp" -#include "v3/include/AsyncDeleteAction.hpp" -#include "v3/include/AsyncWatchAction.hpp" -#include "v3/include/AsyncLeaseGrantAction.hpp" -#include "v3/include/AsyncLockAction.hpp" -#include "v3/include/AsyncTxnAction.hpp" +#include "etcd/v3/AsyncSetAction.hpp" +#include "etcd/v3/AsyncCompareAndSwapAction.hpp" +#include "etcd/v3/AsyncCompareAndDeleteAction.hpp" +#include "etcd/v3/AsyncUpdateAction.hpp" +#include "etcd/v3/AsyncGetAction.hpp" +#include "etcd/v3/AsyncDeleteAction.hpp" +#include "etcd/v3/AsyncWatchAction.hpp" +#include "etcd/v3/AsyncLeaseGrantAction.hpp" +#include "etcd/v3/AsyncLockAction.hpp" +#include "etcd/v3/AsyncTxnAction.hpp" +#include using grpc::Channel; +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; + hints.ai_protocol = IPPROTO_TCP; -etcd::Client::Client(std::string const & address) -{ - std::string stripped_address; - std::string substr("://"); - std::string::size_type i = address.find(substr); - if(i != std::string::npos) - { - stripped_address = address.substr(i+substr.length()); + std::vector target_parts; + boost::split(target_parts, target, boost::is_any_of(":")); + if (target_parts.size() != 2) { + std::cerr << "warn: invalid URL: " << target << std::endl; + return false; } - std::shared_ptr channel = grpc::CreateChannel(stripped_address, grpc::InsecureChannelCredentials()); - std::cout << "channel is: " << channel << std::endl; + if (getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs) != 0) { + std::cerr << "warn: getaddrinfo() failed for endpoint " << target << std::endl; + return false; + } + + 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); + endpoints.emplace_back(std::string(host) + ":" + target_parts[1]); + } + freeaddrinfo(addrs); + return true; +} + +etcd::Client::Client(std::string const & address, std::string const & load_balancer) +{ + std::vector addresses; + boost::algorithm::split(addresses, address, boost::algorithm::is_any_of(",;")); + std::string stripped_address; + { + std::vector stripped_addresses; + std::string substr("://"); + 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()); + dns_resolve(target, stripped_addresses); + } + stripped_address = boost::algorithm::join(stripped_addresses, ","); + } + grpc::ChannelArguments grpc_args; + grpc_args.SetLoadBalancingPolicyName(load_balancer); + std::shared_ptr channel = grpc::CreateCustomChannel( + "ipv4:///" + stripped_address, + grpc::InsecureChannelCredentials(), + grpc_args); stub_= KV::NewStub(channel); watchServiceStub= Watch::NewStub(channel); leaseServiceStub= Lease::NewStub(channel); diff --git a/src/Response.cpp b/src/Response.cpp index 06774ac..6e01a4c 100644 --- a/src/Response.cpp +++ b/src/Response.cpp @@ -1,10 +1,10 @@ #include "etcd/Response.hpp" -#include "v3/include/V3Response.hpp" +#include "etcd/v3/V3Response.hpp" #include -etcd::Response::Response(const etcdv3::V3Response& reply) +etcd::Response::Response(const etcdv3::V3Response& reply, std::chrono::microseconds const& duration) { _index = reply.get_index(); _action = reply.get_action(); @@ -28,6 +28,9 @@ etcd::Response::Response(const etcdv3::V3Response& reply) _lock_key = reply.get_lock_key(); _events = reply.get_events(); + + // duration + _duration = duration; } @@ -105,4 +108,8 @@ std::string const & etcd::Response::lock_key() const { std::vector const & etcd::Response::events() const { return this->_events; -}; +} + +std::chrono::microseconds const& etcd::Response::duration() const { + return this->_duration; +} diff --git a/src/Value.cpp b/src/Value.cpp index 9d0ff59..00d5f46 100644 --- a/src/Value.cpp +++ b/src/Value.cpp @@ -1,6 +1,6 @@ #include #include "etcd/Value.hpp" -#include "v3/include/KeyValue.hpp" +#include "etcd/v3/KeyValue.hpp" etcd::Value::Value() : dir(false), diff --git a/src/Watcher.cpp b/src/Watcher.cpp index ec7fa50..da4db1a 100644 --- a/src/Watcher.cpp +++ b/src/Watcher.cpp @@ -1,5 +1,5 @@ #include "etcd/Watcher.hpp" -#include "v3/include/AsyncWatchAction.hpp" +#include "etcd/v3/AsyncWatchAction.hpp" etcd::Watcher::Watcher(std::string const & address, std::string const & key, std::function callback) { diff --git a/v3/src/Action.cpp b/src/v3/Action.cpp similarity index 68% rename from v3/src/Action.cpp rename to src/v3/Action.cpp index 17b762f..0d9cc4d 100644 --- a/v3/src/Action.cpp +++ b/src/v3/Action.cpp @@ -1,9 +1,10 @@ #include -#include "v3/include/Action.hpp" +#include "etcd/v3/Action.hpp" etcdv3::Action::Action(etcdv3::ActionParameters params) { parameters = params; + start_timepoint = std::chrono::high_resolution_clock::now(); } etcdv3::ActionParameters::ActionParameters() @@ -27,3 +28,6 @@ void etcdv3::Action::waitForResponse() GPR_ASSERT(got_tag == (void*)this); } +const std::chrono::high_resolution_clock::time_point etcdv3::Action::startTimepoint() { + return this->start_timepoint; +} diff --git a/v3/src/AsyncCompareAndDeleteAction.cpp b/src/v3/AsyncCompareAndDeleteAction.cpp similarity index 92% rename from v3/src/AsyncCompareAndDeleteAction.cpp rename to src/v3/AsyncCompareAndDeleteAction.cpp index b626380..50cee11 100644 --- a/v3/src/AsyncCompareAndDeleteAction.cpp +++ b/src/v3/AsyncCompareAndDeleteAction.cpp @@ -1,6 +1,6 @@ -#include "v3/include/AsyncCompareAndDeleteAction.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/AsyncCompareAndDeleteAction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::Compare; using etcdserverpb::RangeRequest; diff --git a/v3/src/AsyncCompareAndSwapAction.cpp b/src/v3/AsyncCompareAndSwapAction.cpp similarity index 93% rename from v3/src/AsyncCompareAndSwapAction.cpp rename to src/v3/AsyncCompareAndSwapAction.cpp index 85974e8..5e813fd 100644 --- a/v3/src/AsyncCompareAndSwapAction.cpp +++ b/src/v3/AsyncCompareAndSwapAction.cpp @@ -1,6 +1,6 @@ -#include "v3/include/AsyncCompareAndSwapAction.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/AsyncCompareAndSwapAction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::Compare; using etcdserverpb::RangeRequest; diff --git a/v3/src/AsyncDeleteAction.cpp b/src/v3/AsyncDeleteAction.cpp similarity index 91% rename from v3/src/AsyncDeleteAction.cpp rename to src/v3/AsyncDeleteAction.cpp index 5002c1b..045321a 100644 --- a/v3/src/AsyncDeleteAction.cpp +++ b/src/v3/AsyncDeleteAction.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncDeleteAction.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncDeleteAction.hpp" +#include "etcd/v3/action_constants.hpp" using etcdserverpb::DeleteRangeRequest; diff --git a/v3/src/AsyncDeleteRangeResponse.cpp b/src/v3/AsyncDeleteRangeResponse.cpp similarity index 87% rename from v3/src/AsyncDeleteRangeResponse.cpp rename to src/v3/AsyncDeleteRangeResponse.cpp index ad4feef..b023284 100644 --- a/v3/src/AsyncDeleteRangeResponse.cpp +++ b/src/v3/AsyncDeleteRangeResponse.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncDeleteRangeResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncDeleteRangeResponse.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::AsyncDeleteRangeResponse::ParseResponse(std::string const& key, bool prefix, DeleteRangeResponse& resp) diff --git a/v3/src/AsyncGetAction.cpp b/src/v3/AsyncGetAction.cpp similarity index 92% rename from v3/src/AsyncGetAction.cpp rename to src/v3/AsyncGetAction.cpp index c2aadd1..5d76e06 100644 --- a/v3/src/AsyncGetAction.cpp +++ b/src/v3/AsyncGetAction.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncGetAction.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncGetAction.hpp" +#include "etcd/v3/action_constants.hpp" using etcdserverpb::RangeRequest; diff --git a/v3/src/AsyncLeaseGrantAction.cpp b/src/v3/AsyncLeaseGrantAction.cpp similarity index 85% rename from v3/src/AsyncLeaseGrantAction.cpp rename to src/v3/AsyncLeaseGrantAction.cpp index 087f658..5b620b3 100644 --- a/v3/src/AsyncLeaseGrantAction.cpp +++ b/src/v3/AsyncLeaseGrantAction.cpp @@ -1,6 +1,6 @@ -#include "v3/include/AsyncLeaseGrantAction.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/AsyncLeaseGrantAction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::LeaseGrantRequest; diff --git a/v3/src/AsyncLeaseGrantResponse.cpp b/src/v3/AsyncLeaseGrantResponse.cpp similarity index 69% rename from v3/src/AsyncLeaseGrantResponse.cpp rename to src/v3/AsyncLeaseGrantResponse.cpp index f718ef2..b5b6a1d 100644 --- a/v3/src/AsyncLeaseGrantResponse.cpp +++ b/src/v3/AsyncLeaseGrantResponse.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncLeaseGrantResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncLeaseGrantResponse.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::AsyncLeaseGrantResponse::ParseResponse(LeaseGrantResponse& resp) diff --git a/v3/src/AsyncLockAction.cpp b/src/v3/AsyncLockAction.cpp similarity index 94% rename from v3/src/AsyncLockAction.cpp rename to src/v3/AsyncLockAction.cpp index 448fa97..55354a0 100644 --- a/v3/src/AsyncLockAction.cpp +++ b/src/v3/AsyncLockAction.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncLockAction.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncLockAction.hpp" +#include "etcd/v3/action_constants.hpp" using v3lockpb::LockRequest; using v3lockpb::UnlockRequest; diff --git a/v3/src/AsyncLockResponse.cpp b/src/v3/AsyncLockResponse.cpp similarity index 73% rename from v3/src/AsyncLockResponse.cpp rename to src/v3/AsyncLockResponse.cpp index 75a6503..83e163b 100644 --- a/v3/src/AsyncLockResponse.cpp +++ b/src/v3/AsyncLockResponse.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncLockResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncLockResponse.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::AsyncLockResponse::ParseResponse(LockResponse& resp) diff --git a/v3/src/AsyncRangeResponse.cpp b/src/v3/AsyncRangeResponse.cpp similarity index 85% rename from v3/src/AsyncRangeResponse.cpp rename to src/v3/AsyncRangeResponse.cpp index 3288fe2..9b96010 100644 --- a/v3/src/AsyncRangeResponse.cpp +++ b/src/v3/AsyncRangeResponse.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncRangeResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncRangeResponse.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::AsyncRangeResponse::ParseResponse(RangeResponse& resp, bool prefix) diff --git a/v3/src/AsyncSetAction.cpp b/src/v3/AsyncSetAction.cpp similarity index 92% rename from v3/src/AsyncSetAction.cpp rename to src/v3/AsyncSetAction.cpp index 3425054..0c28c3f 100644 --- a/v3/src/AsyncSetAction.cpp +++ b/src/v3/AsyncSetAction.cpp @@ -1,6 +1,6 @@ -#include "v3/include/AsyncSetAction.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/AsyncSetAction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::Compare; diff --git a/v3/src/AsyncTxnAction.cpp b/src/v3/AsyncTxnAction.cpp similarity index 88% rename from v3/src/AsyncTxnAction.cpp rename to src/v3/AsyncTxnAction.cpp index 08dd5c6..b519ada 100644 --- a/v3/src/AsyncTxnAction.cpp +++ b/src/v3/AsyncTxnAction.cpp @@ -1,6 +1,6 @@ -#include "v3/include/action_constants.hpp" -#include "v3/include/AsyncTxnAction.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/AsyncTxnAction.hpp" +#include "etcd/v3/Transaction.hpp" etcdv3::AsyncTxnAction::AsyncTxnAction(etcdv3::ActionParameters param, etcdv3::Transaction const &tx) diff --git a/v3/src/AsyncTxnResponse.cpp b/src/v3/AsyncTxnResponse.cpp similarity index 88% rename from v3/src/AsyncTxnResponse.cpp rename to src/v3/AsyncTxnResponse.cpp index b3b08a0..8816206 100644 --- a/v3/src/AsyncTxnResponse.cpp +++ b/src/v3/AsyncTxnResponse.cpp @@ -1,7 +1,7 @@ -#include "v3/include/AsyncTxnResponse.hpp" -#include "v3/include/AsyncRangeResponse.hpp" -#include "v3/include/AsyncDeleteRangeResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncTxnResponse.hpp" +#include "etcd/v3/AsyncRangeResponse.hpp" +#include "etcd/v3/AsyncDeleteRangeResponse.hpp" +#include "etcd/v3/action_constants.hpp" using etcdserverpb::ResponseOp; diff --git a/v3/src/AsyncUpdateAction.cpp b/src/v3/AsyncUpdateAction.cpp similarity index 88% rename from v3/src/AsyncUpdateAction.cpp rename to src/v3/AsyncUpdateAction.cpp index 310f3c4..c985ce2 100644 --- a/v3/src/AsyncUpdateAction.cpp +++ b/src/v3/AsyncUpdateAction.cpp @@ -1,7 +1,7 @@ -#include "v3/include/AsyncUpdateAction.hpp" -#include "v3/include/AsyncRangeResponse.hpp" -#include "v3/include/action_constants.hpp" -#include "v3/include/Transaction.hpp" +#include "etcd/v3/AsyncUpdateAction.hpp" +#include "etcd/v3/AsyncRangeResponse.hpp" +#include "etcd/v3/action_constants.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::Compare; using etcdserverpb::RangeRequest; diff --git a/v3/src/AsyncWatchAction.cpp b/src/v3/AsyncWatchAction.cpp similarity index 69% rename from v3/src/AsyncWatchAction.cpp rename to src/v3/AsyncWatchAction.cpp index 5f7dcbd..5eba8e7 100644 --- a/v3/src/AsyncWatchAction.cpp +++ b/src/v3/AsyncWatchAction.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncWatchAction.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncWatchAction.hpp" +#include "etcd/v3/action_constants.hpp" using etcdserverpb::RangeRequest; @@ -36,21 +36,20 @@ etcdv3::AsyncWatchAction::AsyncWatchAction(etcdv3::ActionParameters param) } else { throw std::runtime_error("failed to create a watch connection"); } - - // wait "write" success - if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)"write") { - stream->Read(&reply, (void*)this); - } else { - throw std::runtime_error("failed to read proper reply from server"); - } } - void etcdv3::AsyncWatchAction::waitForResponse() { void* got_tag; bool ok = false; - + + // wait "write" (WatchCreateRequest) success, and start to read the first reply + if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)"write") { + stream->Read(&reply, (void*)this); + } else { + throw std::runtime_error("failed to write WatchCreateRequest to server"); + } + while(cq_.Next(&got_tag, &ok)) { if(ok == false) @@ -64,12 +63,22 @@ void etcdv3::AsyncWatchAction::waitForResponse() } if(got_tag == (void*)this) // read tag { - if(reply.events_size()) - { + if ((reply.created() && reply.header().revision() < parameters.revision) || + reply.events_size() > 0) { + // we stop watch under two conditions: + // + // 1. watch for a future revision, return immediately with empty events set + // 2. receive any effective events. stream->WritesDone((void*)"writes done"); + + // 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; + } } else { + // otherwise, start next round read-reply stream->Read(&reply, (void*)this); } } @@ -105,8 +114,12 @@ void etcdv3::AsyncWatchAction::waitForResponse(std::function( + std::chrono::high_resolution_clock::now() - start_timepoint); + callback(etcd::Response(resp, duration)); } stream->Read(&reply, (void*)this); } diff --git a/v3/src/AsyncWatchResponse.cpp b/src/v3/AsyncWatchResponse.cpp similarity index 78% rename from v3/src/AsyncWatchResponse.cpp rename to src/v3/AsyncWatchResponse.cpp index f1eebc5..d4dad4e 100644 --- a/v3/src/AsyncWatchResponse.cpp +++ b/src/v3/AsyncWatchResponse.cpp @@ -1,5 +1,5 @@ -#include "v3/include/AsyncWatchResponse.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/AsyncWatchResponse.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) { @@ -7,8 +7,6 @@ void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply) for (auto const &e: reply.events()) { events.emplace_back(e); } - std::cout << "index = " << index << ", event size = " << reply.events().size() - << ", res event size = " << events.size() << std::endl; for(int cnt =0; cnt < reply.events_size(); cnt++) { auto event = reply.events(cnt); diff --git a/v3/src/KeyValue.cpp b/src/v3/KeyValue.cpp similarity index 82% rename from v3/src/KeyValue.cpp rename to src/v3/KeyValue.cpp index 3342536..d3ab6d9 100644 --- a/v3/src/KeyValue.cpp +++ b/src/v3/KeyValue.cpp @@ -1,4 +1,4 @@ -#include "v3/include/KeyValue.hpp" +#include "etcd/v3/KeyValue.hpp" etcdv3::KeyValue::KeyValue() { diff --git a/v3/src/Transaction.cpp b/src/v3/Transaction.cpp similarity index 99% rename from v3/src/Transaction.cpp rename to src/v3/Transaction.cpp index 82beafb..d1b32db 100644 --- a/v3/src/Transaction.cpp +++ b/src/v3/Transaction.cpp @@ -1,4 +1,4 @@ -#include "v3/include/Transaction.hpp" +#include "etcd/v3/Transaction.hpp" using etcdserverpb::Compare; using etcdserverpb::RangeRequest; diff --git a/v3/src/V3Response.cpp b/src/v3/V3Response.cpp similarity index 94% rename from v3/src/V3Response.cpp rename to src/v3/V3Response.cpp index 84b5c58..3e76730 100644 --- a/v3/src/V3Response.cpp +++ b/src/v3/V3Response.cpp @@ -1,5 +1,5 @@ -#include "v3/include/V3Response.hpp" -#include "v3/include/action_constants.hpp" +#include "etcd/v3/V3Response.hpp" +#include "etcd/v3/action_constants.hpp" void etcdv3::V3Response::set_error_code(int code) { diff --git a/v3/src/action_constants.cpp b/src/v3/action_constants.cpp similarity index 91% rename from v3/src/action_constants.cpp rename to src/v3/action_constants.cpp index a3be172..891ac1e 100644 --- a/v3/src/action_constants.cpp +++ b/src/v3/action_constants.cpp @@ -1,4 +1,4 @@ -#include "v3/include/action_constants.hpp" +#include "etcd/v3/action_constants.hpp" char const * etcdv3::CREATE_ACTION = "create"; char const * etcdv3::COMPARESWAP_ACTION = "compareAndSwap"; @@ -10,4 +10,3 @@ char const * etcdv3::COMPAREDELETE_ACTION = "compareAndDelete"; char const * etcdv3::LOCK_ACTION = "lock"; char const * etcdv3::UNLOCK_ACTION = "unlock"; char const * etcdv3::TXN_ACTION = "txn"; -