From 8d0f533a0def0d7bacd382b1a41f15da4689fe48 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 2 Jun 2018 12:53:02 +0200 Subject: [PATCH] F #2147: Better timeouts for xml-rpc clients. Updated oned.conf with default XML-RPC timeout. --- share/etc/oned.conf | 2 +- src/client/Client.cc | 36 +++++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 3e9086cb05..3c641b6f53 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -161,7 +161,7 @@ RAFT = [ LOG_PURGE_TIMEOUT = 600, ELECTION_TIMEOUT_MS = 2500, BROADCAST_TIMEOUT_MS = 500, - XMLRPC_TIMEOUT_MS = 0 + XMLRPC_TIMEOUT_MS = 450 ] # Executed when a server transits from follower->leader diff --git a/src/client/Client.cc b/src/client/Client.cc index 466131baad..4ce90315ee 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -240,32 +240,50 @@ int Client::call(const std::string& endpoint, const std::string& method, const xmlrpc_c::paramList& plist, unsigned int _timeout, xmlrpc_c::value * const result, std::string& error) { - xmlrpc_c::clientXmlTransport_curl transport( - xmlrpc_c::clientXmlTransport_curl::constrOpt().timeout(_timeout)); +// Transport timeouts are not reliably implemented, interrupt flag and async +// client performs better. +// xmlrpc_c::clientXmlTransport_curl transport( +// xmlrpc_c::clientXmlTransport_curl::constrOpt().timeout(_timeout)); + xmlrpc_c::clientXmlTransport_curl transport; xmlrpc_c::carriageParm_curl0 carriage(endpoint); xmlrpc_c::client_xml client(&transport); xmlrpc_c::rpcPtr rpc_client(method, plist); - int xml_rc = 0; + int xml_rc = 0; + int int_flag = 0; try { rpc_client->start(&client, &carriage); - client.finishAsync(xmlrpc_c::timeout()); + client.setInterrupt(&int_flag); - if ( rpc_client->isSuccessful() ) + client.finishAsync(_timeout); + + if ( rpc_client->isFinished() ) { - *result = rpc_client->getResult(); + if ( rpc_client->isSuccessful() ) + { + *result = rpc_client->getResult(); + } + else //RPC failed + { + xmlrpc_c::fault failure = rpc_client->getFault(); + + error = failure.getDescription(); + xml_rc = -1; + } } - else //RPC failed + else //rpc not finished. Interrupt it { - xmlrpc_c::fault failure = rpc_client->getFault(); + int_flag = 1; - error = failure.getDescription(); + error = "RPC call timed out and aborted"; xml_rc = -1; + + client.finishAsync(xmlrpc_c::timeout()); } } catch (exception const& e)