From f0f9c4e8c223e63e3d9e4694d42fc61008e12405 Mon Sep 17 00:00:00 2001 From: Tao He Date: Tue, 14 Mar 2023 19:43:37 +0800 Subject: [PATCH] Enhance the campaign test and document the behaviour when timeout is set (#205) Signed-off-by: Tao He --- README.md | 4 ++ src/v3/AsyncElectionAction.cpp | 4 +- tst/CampaignTest.cpp | 69 +++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 19410a2..97ba367 100644 --- a/README.md +++ b/README.md @@ -884,6 +884,10 @@ pplx::task resign(std::string const &name, int64_t lease_id, std::string const &key, int64_t revision); ``` +Note that if grpc timeout is set, `campaign()` will return an timeout error response if it +cannot acquire the election ownership within the timeout period. Otherwise will block until +become the leader. + The `Observer` returned by `observe()` can be use to monitor the changes of election ownership. The observer stream will be canceled when been destructed. diff --git a/src/v3/AsyncElectionAction.cpp b/src/v3/AsyncElectionAction.cpp index b328997..2428ff4 100644 --- a/src/v3/AsyncElectionAction.cpp +++ b/src/v3/AsyncElectionAction.cpp @@ -31,12 +31,12 @@ etcdv3::AsyncCampaignResponse etcdv3::AsyncCampaignAction::ParseResponse() { AsyncCampaignResponse campaign_resp; campaign_resp.set_action(etcdv3::CAMPAIGN_ACTION); - + 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; diff --git a/tst/CampaignTest.cpp b/tst/CampaignTest.cpp index 0781073..2893824 100644 --- a/tst/CampaignTest.cpp +++ b/tst/CampaignTest.cpp @@ -13,7 +13,7 @@ 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"); -TEST_CASE("campaign and loadership using keepalive") { +TEST_CASE("campaign and leadership using keepalive") { etcd::Client etcd(etcd_uri); auto keepalive = etcd.leasekeepalive(5).get(); auto lease_id = keepalive->Lease(); @@ -32,8 +32,73 @@ TEST_CASE("campaign and loadership using keepalive") { std::cout << "finish campaign" << std::endl; auto resp2 = etcd.leader("/leader").get(); - std::cout << resp2.value().as_string() << std::endl; + CHECK(0 == resp2.error_code()); + CHECK(value == resp2.value().as_string()); + CHECK(resp1.value().key() == resp2.value().key()); std::cout << resp2.value().key() << std::endl; std::cout << "finish leader" << std::endl; + + 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"); + + auto fn1 = [&]() { + etcd::Client etcd(etcd_uri); + auto keepalive = etcd.leasekeepalive(5).get(); + auto lease_id = keepalive->Lease(); + auto resp1 = etcd.campaign("/leader", lease_id, value1).get(); + CHECK(0 == resp1.error_code()); + + 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(); + CHECK(0 == resp2.error_code()); + }; + + auto fn2 = [&]() { + etcd::Client etcd(etcd_uri); + auto keepalive = etcd.leasekeepalive(5).get(); + auto lease_id = keepalive->Lease(); + + // set client timeout + etcd.set_grpc_timeout(std::chrono::seconds(3)); + + std::this_thread::sleep_for(std::chrono::seconds(3)); + auto resp1 = etcd.campaign("/leader", lease_id, value2).get(); + std::cout <