support for server timeout

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1214 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 18 years ago
parent 0dec77b98c
commit 352b0e8d20

@ -13,7 +13,7 @@ plug_in_name = xmlrpc2di
# -D XMLRPCPP_SUPPORT_STRUCT_ACCESS
# use these for local installation:
module_cflags = -I$(XMLRPCPP_DIR)/src -DHAVE_XMLRPCPP_SSL
module_cflags = -I$(XMLRPCPP_DIR)/src -DHAVE_XMLRPCPP_SSL -D XMLRPCPP_SUPPORT_STRUCT_ACCESS
module_extra_objs = $(XMLRPCPP_DIR)/libXmlRpc.a
extra_clean = clean_libxmlrpc
# and comment module_ldflags line above

@ -0,0 +1,42 @@
#include "XmlRpc.h"
#include "TOXmlRpcClient.h"
// Clear the referenced flag even if exceptions or errors occur.
struct ClearFlagOnExit {
ClearFlagOnExit(bool& flag) : _flag(flag) {}
~ClearFlagOnExit() { _flag = false; }
bool& _flag;
};
bool TOXmlRpcClient::execute(const char* method, XmlRpcValue const& params, XmlRpcValue& result, double timeout) {
XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s (_connectionState %d).", method, _connectionState);
// This is not a thread-safe operation, if you want to do multithreading, use separate
// clients for each thread. If you want to protect yourself from multiple threads
// accessing the same client, replace this code with a real mutex.
if (_executing)
return false;
_executing = true;
ClearFlagOnExit cf(_executing);
_sendAttempts = 0;
_isFault = false;
if ( ! setupConnection())
return false;
if ( ! generateRequest(method, params))
return false;
result.clear();
// double msTime = -1.0; // Process until exit is called
_disp.work(timeout);
if (_connectionState != IDLE || ! parseResponse(result))
return false;
XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s completed.", method);
_response = "";
return true;
}

@ -0,0 +1,24 @@
#ifndef _TO_XMLRPCCLIENT_H
#define _TO_XMLRPCCLIENT_H
#include "XmlRpcClient.h"
using namespace XmlRpc;
/* xmlrpc client with timeout */
class TOXmlRpcClient : public XmlRpc::XmlRpcClient {
public:
TOXmlRpcClient(const char* host, int port, const char* uri=0
#ifdef HAVE_XMLRPCPP_SSL
, bool ssl=false
#endif
)
: XmlRpcClient(host, port, uri
#ifdef HAVE_XMLRPCPP_SSL
, ssl
#endif
) { }
bool execute(const char* method, XmlRpcValue const& params,
XmlRpcValue& result, double timeout);
};
#endif

@ -32,6 +32,7 @@
#include "AmUtils.h"
#include "AmArg.h"
#include "AmSession.h"
#include "TOXmlRpcClient.h"
#define MOD_NAME "xmlrpc2di"
@ -43,6 +44,8 @@ XMLRPC2DI* XMLRPC2DI::_instance=0;
// retry a failed server after 10 seconds
unsigned int XMLRPC2DI::ServerRetryAfter = 10;
double XMLRPC2DI::ServerTimeout = -1;
XMLRPC2DI* XMLRPC2DI::instance()
{
if(_instance == NULL){
@ -94,6 +97,21 @@ int XMLRPC2DI::load() {
ServerRetryAfter = cfg.getParameterInt("server_retry_after", 10);
DBG("retrying failed server after %u seconds\n", ServerRetryAfter);
string server_timeout = cfg.getParameter("server_timeout");
if (!server_timeout.empty()) {
unsigned int server_timeout_i = 0;
if (str2i(server_timeout, server_timeout_i)) {
ERROR("could not understand server_timeout=%s\n",
server_timeout.c_str());
return -1;
}
if (server_timeout_i) {
ServerTimeout = (double)server_timeout_i/1000.0; // in millisec
}
}
string run_server = cfg.getParameter("run_server","yes");
if (run_server != "yes") {
DBG("XMLRPC server will not be started.\n");
@ -203,7 +221,7 @@ void XMLRPC2DI::sendRequest(const AmArg& args, AmArg& ret) {
ret.push("no active connections");
return;
}
XmlRpcClient c((const char*)srv->server.c_str(), (int)srv->port,
TOXmlRpcClient c((const char*)srv->server.c_str(), (int)srv->port,
(const char*)srv->uri.empty()?NULL:srv->uri.c_str()
#ifdef HAVE_XMLRPCPP_SSL
, false
@ -212,7 +230,8 @@ void XMLRPC2DI::sendRequest(const AmArg& args, AmArg& ret) {
XmlRpcValue x_args, x_result;
XMLRPC2DIServer::amarg2xmlrpcval(params, x_args);
if (c.execute(method.c_str(), x_args, x_result) && !c.isFault()) {
if (c.execute(method.c_str(), x_args, x_result, XMLRPC2DI::ServerTimeout) && !c.isFault()) {
DBG("successfully executed method %s on server %s:%d\n",
method.c_str(), srv->server.c_str(), srv->port);
ret.push(0);
@ -239,7 +258,7 @@ void XMLRPC2DI::sendRequestList(const AmArg& args, AmArg& ret) {
ret.push("no active connections");
return;
}
XmlRpcClient c((const char*)srv->server.c_str(), (int)srv->port,
TOXmlRpcClient c((const char*)srv->server.c_str(), (int)srv->port,
(const char*)srv->uri.empty()?NULL:srv->uri.c_str()
#ifdef HAVE_XMLRPCPP_SSL
, false
@ -253,7 +272,7 @@ void XMLRPC2DI::sendRequestList(const AmArg& args, AmArg& ret) {
XMLRPC2DIServer::amarg2xmlrpcval(args.get(i), x_args[i-2]);
}
if (c.execute(method.c_str(), x_args, x_result) && !c.isFault()) {
if (c.execute(method.c_str(), x_args, x_result, XMLRPC2DI::ServerTimeout) && !c.isFault()) {
DBG("successfully executed method %s on server %s:%d\n",
method.c_str(), srv->server.c_str(), srv->port);
ret.push(0);
@ -476,13 +495,13 @@ void XMLRPC2DIServer::xmlrpcval2amarg(XmlRpcValue& v, AmArg& a,
xmlrpcval2amarg(v[i], a[a.size()-1], 0);
} break;
#ifdef XMLRPCPP_SUPPORT_STRUCT_ACCESS
case XmlRpcValue::TypeStruct: {
for (XmlRpc::XmlRpcValue::ValueStruct::iterator it=
((XmlRpcValue::ValueStruct)v).begin();
it != ((XmlRpcValue::ValueStruct)v).end(); it++) {
a[it->first] = AmArg();
xmlrpcval2amarg(it->second, a[it->first], 0);
}
case XmlRpcValue::TypeStruct: {
for (XmlRpc::XmlRpcValue::ValueStruct::iterator it=
((XmlRpcValue::ValueStruct)v).begin();
it != ((XmlRpcValue::ValueStruct)v).end(); it++) {
a[it->first] = AmArg();
xmlrpcval2amarg(it->second, a[it->first], 0);
}
} break;
#endif

@ -157,6 +157,8 @@ class XMLRPC2DI
const AmArg& args, AmArg& ret);
static unsigned int ServerRetryAfter;
static double ServerTimeout;
};
#endif

@ -25,3 +25,7 @@ xmlrpc_port=8090
# run the XMLRPC server at all (default: yes)
#
# run_server=yes
# timeout for client requests, in milliseconds (0 to disable)
#
# server_timeout=500

Loading…
Cancel
Save