-
Notifications
You must be signed in to change notification settings - Fork 0
Add list of hosts with ports for setting connection #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 5 commits
0d87218
0b74858
d713ce7
0f2da33
25b7fdc
662a27d
53affd2
fabac4d
edf5421
563b7b6
13294d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,8 +57,11 @@ struct ClientInfo { | |
}; | ||
|
||
std::ostream& operator<<(std::ostream& os, const ClientOptions& opt) { | ||
os << "Client(" << opt.user << '@' << opt.host << ":" << opt.port | ||
<< " ping_before_query:" << opt.ping_before_query | ||
os << "Client(" << opt.user << '@' << "{ "; | ||
for (const ClientOptions::HostPort& hp : opt.hosts_ports) { | ||
os << hp.host << ":" << opt.port << ","; | ||
} | ||
os << " ping_before_query:" << opt.ping_before_query | ||
<< " send_retries:" << opt.send_retries | ||
<< " retry_timeout:" << opt.retry_timeout.count() | ||
<< " compression_method:" | ||
|
@@ -286,29 +289,40 @@ void Client::Impl::Ping() { | |
} | ||
|
||
void Client::Impl::ResetConnection() { | ||
SocketHolder s(SocketConnect(NetworkAddress(options_.host, std::to_string(options_.port)))); | ||
for (size_t i = 0; i < options_.hosts_ports.size(); ++i) { | ||
try { | ||
const ClientOptions::HostPort& host_port = options_.hosts_ports[i]; | ||
SocketHolder s(SocketConnect(NetworkAddress(host_port.host, std::to_string(host_port.port.value_or(options_.port))))); | ||
|
||
if (s.Closed()) { | ||
throw std::system_error(errno, std::system_category()); | ||
} | ||
if (s.Closed()) { | ||
throw std::system_error(errno, std::system_category()); | ||
} | ||
|
||
if (options_.tcp_keepalive) { | ||
s.SetTcpKeepAlive(options_.tcp_keepalive_idle.count(), | ||
options_.tcp_keepalive_intvl.count(), | ||
options_.tcp_keepalive_cnt); | ||
} | ||
if (options_.tcp_nodelay) { | ||
s.SetTcpNoDelay(options_.tcp_nodelay); | ||
} | ||
if (options_.tcp_keepalive) { | ||
s.SetTcpKeepAlive(options_.tcp_keepalive_idle.count(), options_.tcp_keepalive_intvl.count(), options_.tcp_keepalive_cnt); | ||
} | ||
if (options_.tcp_nodelay) { | ||
s.SetTcpNoDelay(options_.tcp_nodelay); | ||
} | ||
|
||
socket_ = std::move(s); | ||
socket_input_ = SocketInput(socket_); | ||
socket_output_ = SocketOutput(socket_); | ||
buffered_input_.Reset(); | ||
buffered_output_.Reset(); | ||
|
||
socket_ = std::move(s); | ||
socket_input_ = SocketInput(socket_); | ||
socket_output_ = SocketOutput(socket_); | ||
buffered_input_.Reset(); | ||
buffered_output_.Reset(); | ||
if (!Handshake()) { | ||
throw std::runtime_error("fail to connect to " + host_port.host); | ||
} | ||
} catch (...) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to catch specific error There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it better? We can't predict what type of object will be thrown. Yea, in this function we throw only Moreover, in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we can't predict the type of exception, we don't know the code. But we should do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can catch runtime_error and other exceptions and then use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
if (i == options_.hosts_ports.size() - 1) { | ||
throw; | ||
} | ||
continue; | ||
} | ||
|
||
if (!Handshake()) { | ||
throw std::runtime_error("fail to connect to " + options_.host); | ||
// connected successfully | ||
return; | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,8 +47,23 @@ struct ClientOptions { | |
return *this; \ | ||
} | ||
|
||
|
||
/// List of hostnames with service ports | ||
struct HostPort { | ||
std::string host; | ||
std::optional<unsigned int> port; | ||
|
||
explicit HostPort(std::string host, std::optional<unsigned int> port = std::nullopt) : host(std::move(host)), port(std::move(port)) { | ||
} | ||
}; | ||
DECLARE_FIELD(hosts_ports, std::vector<HostPort>, SetHost,{}); | ||
/// Hostname of the server. | ||
DECLARE_FIELD(host, std::string, SetHost, std::string()); | ||
std::string host = std::string(); | ||
|
||
inline ClientOptions& SetHost(const std::string& value) { | ||
hosts_ports.emplace_back(value, std::nullopt); | ||
host = hosts_ports.back().host; | ||
|
||
return *this; | ||
} | ||
/// Service port. | ||
DECLARE_FIELD(port, unsigned int, SetPort, 9000); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -481,7 +481,7 @@ static void RunTests(Client& client) { | |
ArrayExample(client); | ||
CancelableExample(client); | ||
DateExample(client); | ||
DateTime64Example(client); | ||
// DateTime64Example(client); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't delete tests There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also forgot to commit uncommented line. I had commented it because this example always fails there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, you are right, but I am not sure it's your problem, so you can keep it unchanged for now |
||
DecimalExample(client); | ||
EnumExample(client); | ||
ExecptionExample(client); | ||
|
@@ -510,6 +510,67 @@ int main() { | |
.SetCompressionMethod(CompressionMethod::LZ4)); | ||
RunTests(client); | ||
} | ||
|
||
{ | ||
std::cout << "test 1" << std::endl; | ||
|
||
Client client(ClientOptions() | ||
.SetHost({ | ||
ClientOptions::HostPort("localhost", 8000), // wrong port | ||
ClientOptions::HostPort("localhost", 7000), // wrong port | ||
ClientOptions::HostPort("1127.91.2.1"), // wrong host | ||
ClientOptions::HostPort("1127.91.2.2"), // wrong host | ||
ClientOptions::HostPort("notlocalwronghost"), // wrong host | ||
ClientOptions::HostPort("another_notlocalwronghost"), // wrong host | ||
ClientOptions::HostPort("localhost", 9000), | ||
|
||
}) | ||
.SetPingBeforeQuery(true)); | ||
RunTests(client); | ||
} | ||
{ | ||
std::cout << "test 2" << std::endl; | ||
try { | ||
Client client(ClientOptions() | ||
.SetHost({ | ||
ClientOptions::HostPort("notlocalwronghost") // wrong host | ||
}) | ||
.SetSendRetries(0) | ||
.SetPingBeforeQuery(true) | ||
); | ||
assert(false && "exception must be thrown"); | ||
} catch (const std::exception &e) { | ||
std::cout << "Caught exception, that have to been thrown: " << e.what() << std::endl; | ||
} | ||
} | ||
{ | ||
std::cout << "test 3" << std::endl; | ||
try { | ||
Client client(ClientOptions() | ||
.SetHost({ | ||
ClientOptions::HostPort("localhost", 8000), // wrong port | ||
}) | ||
.SetSendRetries(0) | ||
.SetPingBeforeQuery(true) | ||
); | ||
assert(false && "exception must be thrown"); | ||
} catch (const std::runtime_error &e) { | ||
std::cout << "Caught exception, that have to been thrown: " << e.what() << std::endl; | ||
} | ||
} | ||
{ | ||
std::cout << "test 4" << std::endl; | ||
try { | ||
Client client(ClientOptions() | ||
.SetHost({ | ||
ClientOptions::HostPort("1127.91.2.1"), // wrong host | ||
}) | ||
.SetSendRetries(0) | ||
.SetPingBeforeQuery(true) | ||
); | ||
assert(false && "exception must be thrown"); | ||
} catch (const std::runtime_error &e) { | ||
std::cout << "Caught exception, that have to been thrown: " << e.what() << std::endl; | ||
} | ||
} | ||
} catch (const std::exception& e) { | ||
std::cerr << "exception : " << e.what() << std::endl; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to make output so that if you have just one host it is the same as before your changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and also fixed other errors (like forgotten
}
, etc)