templates.thrift_cpp.client.perservice.client_provider_if.vm Maven / Gradle / Ivy
#parse("thrift_cpp/include/cxx_schema_include.vm")
#parse("thrift_cpp/include/service_decorator.include.vm")
#parse("thrift_cpp/include/cxx.helper.vm")
#set( $output_basename = ${thrift_clientproviderif.sampleType})
#set( $source_type = "h")
#set( $output_filename = "${output_basename}.${source_type}")
$codewriter.setCurrentCxxFilename("stub",$output_filename)
$header_begin
\#include "${interfaceName}.h"
\#include
#pkg_namespace_begin($interfaceClass.package.name)
/*
* ${thrift_client.type} 实例提供者(thread safe)接口,
* 为调用者返回一个 ${thrift_client.sampleType} 实例
*/
class ${thrift_clientproviderif.sampleType} {
protected:
std::string host;
int port;
std::string masterHost;
int masterPort;
std::string slaveHost;
int slavePort;
bool _disableSlave;
bool _masterFirstly;
/* Connect timeout in mills */
int connTimeout;
/* Send timeout in mills */
int sendTimeout;
/* Receive timeout in mills */
int recvTimeout;
public:
${thrift_clientproviderif.sampleType}() = default;
${thrift_clientproviderif.sampleType}(const std::string & host, int port)
:host(host), port(port), masterHost(host), masterPort(port), slaveHost(), slavePort(0), _disableSlave(false), _masterFirstly(false){}
virtual ~${thrift_clientproviderif.sampleType}() {}
/** return transport object with host and port */
virtual ::apache::thrift::transport::TTransport& getTransport() const = 0;
/** 重新指定主机和端口号,子类重写此函数时务必调用父类函数 */
virtual void resetClient(const std::string & host, int port)
{
this->host = host;
this->port = port;
}
virtual ${thrift_client.type}& get() const = 0;
/** 开启传输层 */
void open() {
try
{
getTransport().open();
}
catch (const apache::thrift::transport::TTransportException& e)
{
if (!isUnsolveHost(e) || _disableSlave || slaveHost.empty() || masterHost == slaveHost)
{
throw e;
}
/** 如果设置主服务优先,则当前代码块执行结束时切换回主服务 */
::gdface::raii rel([this]{if (_masterFirstly && host != masterHost)resetClient(masterHost, masterPort); });
/************************************************************************/
/* 如果主机无法访问且设置了备用服务主机,激活重试机制 */
/************************************************************************/
if (host == masterHost) {
/** 切换到备用服务主机 */
resetClient(slaveHost, slavePort > 0 ? slavePort : masterPort);
}
else
{
/** 切换到主服务主机 */
resetClient(masterHost, masterPort);
}
getTransport().open();
}
}
/** 关闭传输层 */
void close() { getTransport().close(); }
${thrift_client.type}& operator*() const { return get(); }
${thrift_client.type}& operator()() const { return get(); }
/** 返回当前连接的主机 */
std::string getHost() const noexcept
{
return this->host;
}
/** 返回当前连接的端口号 */
virtual int getPort() const noexcept
{
return this->port;
}
/** 设置备用服务主机 */
void setSlaveHost(const std::string & host,int port)
{
slaveHost = host;
slavePort = port;
}
// 设置是否禁用备用主机,默认false
// 为true时,在主服务连接失败的情况下不会尝试连接备用服务
void disableSlave(bool disable)
{
_disableSlave = disable;
}
// 设置是否主服务优先,默认false
// 为true时,每次调用首先使用主服务,在主服务连接失败的情况下才会尝试连接备用服务
// 为false时,每次调用当前服务主机(主/备用)连接失败的情况下切换到另一个服务主机,如果服务连接成功,下次调用就作为当前服务主机使用
void masterFirstly(bool firstly)
{
_masterFirstly = firstly;
}
// 设置超时参数
// @param connTimeout Connect timeout in mills,ignore if less than or equal to 0
// @param sendTimeout Send timeout in mills,ignore if less than or equal to 0
// @param recvTimeout Recv timeout in mills,ignore if less than or equal to 0
void setTimeout(int connTimeout, int sendTimeout, int recvTimeout)
{
this->connTimeout = connTimeout;
this->sendTimeout = sendTimeout;
this->recvTimeout = recvTimeout;
}
inline bool isUnsolveHost(const apache::thrift::transport::TTransportException& e)
{
return e.getType() == apache::thrift::transport::TTransportException::TTransportExceptionType::NOT_OPEN;
}
};
#pkg_namespace_end()
$header_end
© 2015 - 2025 Weber Informatics LLC | Privacy Policy