Optimize the implementation of error handling in keep alive. (#54)

Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
Tao He 2021-04-07 23:20:33 +08:00 committed by GitHub
parent cee938fb0a
commit 3e30c4c61d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 9 deletions

View File

@ -12,6 +12,7 @@
namespace etcdv3 { namespace etcdv3 {
class AsyncWatchAction; class AsyncWatchAction;
class AsyncLeaseKeepAliveAction;
class V3Response; class V3Response;
} }
@ -139,6 +140,7 @@ namespace etcd
std::chrono::microseconds _duration; // execute duration (in microseconds), during the action created and response parsed std::chrono::microseconds _duration; // execute duration (in microseconds), during the action created and response parsed
friend class SyncClient; friend class SyncClient;
friend class etcdv3::AsyncWatchAction; friend class etcdv3::AsyncWatchAction;
friend class etcdv3::AsyncLeaseKeepAliveAction;
friend class Client; friend class Client;
}; };
} }

View File

@ -7,6 +7,7 @@
#include "proto/rpc.grpc.pb.h" #include "proto/rpc.grpc.pb.h"
#include "etcd/v3/Action.hpp" #include "etcd/v3/Action.hpp"
#include "etcd/v3/AsyncLeaseResponse.hpp" #include "etcd/v3/AsyncLeaseResponse.hpp"
#include "etcd/Response.hpp"
using grpc::ClientAsyncResponseReader; using grpc::ClientAsyncResponseReader;
using grpc::ClientAsyncReaderWriter; using grpc::ClientAsyncReaderWriter;
@ -45,7 +46,7 @@ namespace etcdv3
AsyncLeaseKeepAliveAction(etcdv3::ActionParameters param); AsyncLeaseKeepAliveAction(etcdv3::ActionParameters param);
AsyncLeaseKeepAliveResponse ParseResponse(); AsyncLeaseKeepAliveResponse ParseResponse();
AsyncLeaseKeepAliveResponse Refresh(); etcd::Response Refresh();
void CancelKeepAlive(); void CancelKeepAlive();
bool Cancelled() const; bool Cancelled() const;

View File

@ -152,9 +152,18 @@ void etcd::KeepAlive::refresh()
std::cerr << "keepalive timer error: " << error << ", " << error.message() << std::endl; std::cerr << "keepalive timer error: " << error << ", " << error.message() << std::endl;
#endif #endif
} else { } else {
this->stubs->call->Refresh(); if (this->continue_next) {
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());
}
if (resp.value().ttl() == -1) {
throw std::runtime_error("Failed to refresh lease due to expiration: the new TTL is -1.");
}
// trigger the next round; // trigger the next round;
this->refresh(); this->refresh();
} }
}
}); });
} }

View File

@ -82,12 +82,16 @@ etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::ParseResp
return lease_resp; return lease_resp;
} }
etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::Refresh() etcd::Response etcdv3::AsyncLeaseKeepAliveAction::Refresh()
{ {
std::lock_guard<std::mutex> scope_lock(this->protect_is_cancelled); std::lock_guard<std::mutex> scope_lock(this->protect_is_cancelled);
auto start_timepoint = std::chrono::high_resolution_clock::now();
if (isCancelled) { if (isCancelled) {
return ParseResponse(); auto resp = ParseResponse();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::high_resolution_clock::now() - start_timepoint);
return etcd::Response(resp, duration);
} }
LeaseKeepAliveRequest leasekeepalive_request; LeaseKeepAliveRequest leasekeepalive_request;
@ -102,10 +106,13 @@ etcdv3::AsyncLeaseKeepAliveResponse etcdv3::AsyncLeaseKeepAliveAction::Refresh()
stream->Read(&reply, (void*)"keepalive read"); stream->Read(&reply, (void*)"keepalive read");
// wait read finish // wait read finish
if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)"keepalive read") { if (cq_.Next(&got_tag, &ok) && ok && got_tag == (void *)"keepalive read") {
return ParseResponse(); auto resp = ParseResponse();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::high_resolution_clock::now() - start_timepoint);
return etcd::Response(resp, duration);
} }
} }
throw std::runtime_error("Failed to create a lease keep-alive connection"); return etcd::Response(grpc::StatusCode::ABORTED, "Failed to create a lease keep-alive connection");
} }
void etcdv3::AsyncLeaseKeepAliveAction::CancelKeepAlive() void etcdv3::AsyncLeaseKeepAliveAction::CancelKeepAlive()

View File

@ -81,10 +81,10 @@ TEST_CASE("create watcher")
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true); etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
std::this_thread::sleep_for(std::chrono::seconds(3)); std::this_thread::sleep_for(std::chrono::seconds(3));
etcd.set("/test/key", "42"); etcd.set("/test/key", "42");
std::this_thread::sleep_for(std::chrono::seconds(3));
etcd.set("/test/key", "43"); etcd.set("/test/key", "43");
std::this_thread::sleep_for(std::chrono::seconds(3)); std::this_thread::sleep_for(std::chrono::seconds(3));
} }
std::this_thread::sleep_for(std::chrono::seconds(10));
CHECK(2 == watcher_called); CHECK(2 == watcher_called);
etcd.rmdir("/test", true).error_code(); etcd.rmdir("/test", true).error_code();
} }