mirror of https://github.com/TarsCloud/TarsCpp
add unitttest
parent
1bdad61e22
commit
6b383550a5
|
@ -1,6 +1,3 @@
|
|||
[submodule "servant/protocol"]
|
||||
path = servant/protocol
|
||||
url = https://github.com/TarsCloud/TarsProtocol.git
|
||||
[submodule "unittest"]
|
||||
path = unittest
|
||||
url = https://github.com/TarsCloud/tars-unittest.git
|
||||
|
|
|
@ -52,12 +52,7 @@ add_subdirectory(servant)
|
|||
|
||||
IF (NOT ${ONLY_LIB})
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(unittest)
|
||||
ENDIF()
|
||||
|
||||
#add_subdirectory(test_deprecated)
|
||||
# IF (UNIX)
|
||||
IF (NOT ${ONLY_LIB} )
|
||||
add_subdirectory(unittest)
|
||||
ENDIF()
|
||||
# ENDIF()
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ macro(build_tars_server MODULE DEPS)
|
|||
|
||||
aux_source_directory(. DIR_SRCS)
|
||||
|
||||
FILE(GLOB TARS_LIST "${CMAKE_CURRENT_SOURCE_DIR}/*.tars")
|
||||
FILE(GLOB PB_LIST "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
|
||||
FILE(GLOB_RECURSE TARS_LIST "${CMAKE_CURRENT_SOURCE_DIR}/*.tars")
|
||||
FILE(GLOB_RECURSE PB_LIST "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
|
||||
|
||||
set(TARS_LIST_DEPENDS)
|
||||
set(PB_LIST_DEPENDS)
|
||||
|
@ -17,19 +17,20 @@ macro(build_tars_server MODULE DEPS)
|
|||
|
||||
foreach (TARS_SRC ${TARS_LIST})
|
||||
get_filename_component(NAME_WE ${TARS_SRC} NAME_WE)
|
||||
get_filename_component(PATH ${TARS_SRC} PATH)
|
||||
|
||||
set(TARS_H ${NAME_WE}.h)
|
||||
|
||||
set(CUR_TARS_GEN ${CMAKE_CURRENT_SOURCE_DIR}/${TARS_H})
|
||||
set(CUR_TARS_GEN ${PATH}/${TARS_H})
|
||||
LIST(APPEND TARS_LIST_DEPENDS ${CUR_TARS_GEN})
|
||||
|
||||
add_custom_command(OUTPUT ${CUR_TARS_GEN}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${TARS2CPP}
|
||||
WORKING_DIRECTORY ${PATH}
|
||||
DEPENDS ${TARS2CPP} ${TARS_SRC}
|
||||
COMMAND ${TARS2CPP} ${TARS_SRC}
|
||||
COMMENT "${TARS2CPP} ${TARS_SRC}")
|
||||
|
||||
list(APPEND CLEAN_LIST ${CMAKE_CURRENT_SOURCE_DIR}/${TARS_H})
|
||||
list(APPEND CLEAN_LIST ${PATH}/${TARS_H})
|
||||
|
||||
endforeach ()
|
||||
|
||||
|
@ -48,21 +49,22 @@ macro(build_tars_server MODULE DEPS)
|
|||
|
||||
foreach (PB_SRC ${PB_LIST})
|
||||
get_filename_component(NAME_WE ${PB_SRC} NAME_WE)
|
||||
get_filename_component(PATH ${PB_SRC} PATH)
|
||||
|
||||
set(PB_H ${NAME_WE}.pb.h)
|
||||
set(PB_CC ${NAME_WE}.pb.cc)
|
||||
|
||||
set(CUR_PB_GEN ${CMAKE_CURRENT_SOURCE_DIR}/${PB_H} ${CMAKE_CURRENT_SOURCE_DIR}/${PB_CC})
|
||||
set(CUR_PB_GEN ${PATH}/${PB_H} ${PATH}/${PB_CC})
|
||||
LIST(APPEND PB_LIST_DEPENDS ${CUR_PB_GEN})
|
||||
|
||||
add_custom_command(OUTPUT ${CUR_PB_GEN}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${PATH}
|
||||
DEPENDS ${PROTO2TARS} ${_PROTOBUF_PROTOC}
|
||||
COMMAND ${_PROTOBUF_PROTOC} -I "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${PB_SRC}" --cpp_out "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "${_PROTOBUF_PROTOC} ${PB_SRC} ${CMAKE_CURRENT_SOURCE_DIR} ${CUR_PB_GEN}")
|
||||
COMMAND ${_PROTOBUF_PROTOC} -I "${PATH}"
|
||||
"${PB_SRC}" --cpp_out "${PATH}"
|
||||
COMMENT "${_PROTOBUF_PROTOC} ${PB_SRC} ${PATH} ${CUR_PB_GEN}")
|
||||
|
||||
list(APPEND CLEAN_LIST ${CMAKE_CURRENT_SOURCE_DIR}/${PB_H} ${CMAKE_CURRENT_SOURCE_DIR}/${PB_CC})
|
||||
list(APPEND CLEAN_LIST ${PATH}/${PB_H} ${PATH}/${PB_CC})
|
||||
endforeach ()
|
||||
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CLEAN_LIST}")
|
||||
|
|
|
@ -24,12 +24,12 @@ endforeach()
|
|||
|
||||
option(ONLY_LIB "option for only lib" ON)
|
||||
|
||||
option(TARS_OPENTRACKING "option for open tracking" OFF)
|
||||
# option(TARS_OPENTRACKING "option for open tracking" OFF)
|
||||
|
||||
if (TARS_OPENTRACKING)
|
||||
add_definitions(-DTARS_OPENTRACKING=1)
|
||||
set(OPENTRACKING_INC "/usr/local/include")
|
||||
endif ()
|
||||
# if (TARS_OPENTRACKING)
|
||||
# add_definitions(-DTARS_OPENTRACKING=1)
|
||||
# set(OPENTRACKING_INC "/usr/local/include")
|
||||
# endif ()
|
||||
|
||||
# set(TARS_OPENTRACKING $ENV{TARS_OPENTRACKING})
|
||||
# if(TARS_OPENTRACKING)
|
||||
|
@ -97,7 +97,7 @@ message("PLATFORM: ${PLATFORM}")
|
|||
message("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
||||
message("BIN: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
message("TARS2CPP: ${TARS2CPP}")
|
||||
message("TARS_OPENTRACKING: ${TARS_OPENTRACKING}")
|
||||
#message("TARS_OPENTRACKING: ${TARS_OPENTRACKING}")
|
||||
message("ONLY_LIB: ${ONLY_LIB}" )
|
||||
#-------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "BServant.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/CoroutineScheduler.h"
|
||||
//#include "servant/CoroutineScheduler.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
@ -24,7 +24,7 @@ using namespace Test;
|
|||
using namespace tars;
|
||||
|
||||
//继承框架的协程类
|
||||
class TestCoroutine : public Coroutine
|
||||
class TestCoroutine : public TC_Coroutine
|
||||
{
|
||||
public:
|
||||
TestCoroutine(int iNum);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "BServant.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/CoroutineScheduler.h"
|
||||
//#include "servant/CoroutineScheduler.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
@ -59,7 +59,7 @@ typedef tars::TC_AutoPtr<BServantCoroCallback> BServantCoroCallbackPtr;
|
|||
|
||||
////////////////////////////////////////////
|
||||
//继承框架的协程类
|
||||
class TestCoroutine : public Coroutine
|
||||
class TestCoroutine : public TC_Coroutine
|
||||
{
|
||||
public:
|
||||
TestCoroutine(int iNum);
|
||||
|
|
|
@ -73,8 +73,10 @@ static TC_NetWorkBuffer::PACKET_TYPE customResponse(TC_NetWorkBuffer &in, Respon
|
|||
/*
|
||||
Whole package length (4 bytes) + irequestid (4 bytes) + package content
|
||||
*/
|
||||
static vector<char> customRequest(RequestPacket& request, Transceiver *)
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> customRequest(RequestPacket& request, TC_Transceiver *)
|
||||
{
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
unsigned int net_bufflength = htonl(request.sBuffer.size()+8);
|
||||
unsigned char * bufflengthptr = (unsigned char*)(&net_bufflength);
|
||||
|
||||
|
@ -89,7 +91,9 @@ static vector<char> customRequest(RequestPacket& request, Transceiver *)
|
|||
memcpy(buffer.data() + sizeof(unsigned int), netrequestIdptr, sizeof(unsigned int));
|
||||
memcpy(buffer.data() + sizeof(unsigned int) * 2, request.sBuffer.data(), request.sBuffer.size());
|
||||
|
||||
return buffer;
|
||||
buff->addBuffer(buffer);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
class CustomCallBack : public ServantProxyCallback
|
||||
|
|
|
@ -55,8 +55,10 @@ static TC_NetWorkBuffer::PACKET_TYPE pushResponse(TC_NetWorkBuffer &in, Response
|
|||
请求包编码函数,本函数的打包格式为
|
||||
整个包长度(4字节)+iRequestId(4字节)+包内容
|
||||
*/
|
||||
static vector<char> pushRequest(RequestPacket& request, Transceiver *)
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> pushRequest(RequestPacket& request, TC_Transceiver *)
|
||||
{
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
unsigned int net_bufflength = htonl(request.sBuffer.size()+8);
|
||||
unsigned char * bufflengthptr = (unsigned char*)(&net_bufflength);
|
||||
|
||||
|
@ -71,7 +73,9 @@ static vector<char> pushRequest(RequestPacket& request, Transceiver *)
|
|||
memcpy(buffer.data() + sizeof(unsigned int), netrequestIdptr, sizeof(unsigned int));
|
||||
memcpy(buffer.data() + sizeof(unsigned int) * 2, request.sBuffer.data(), request.sBuffer.size());
|
||||
|
||||
return buffer;
|
||||
buff->addBuffer(buffer);
|
||||
|
||||
return buff;
|
||||
// sbuff->addBuffer(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ int main(int argc, char *argv[])
|
|||
conf.parseFile(option.getValue("config"));
|
||||
_comm->setProperty(conf);
|
||||
|
||||
// TafRollLogger::getInstance()->logger()->setLogLevel(6);
|
||||
// TarsRollLogger::getInstance()->logger()->setLogLevel(6);
|
||||
|
||||
_comm->setProperty("sendqueuelimit", "1000000");
|
||||
_comm->setProperty("asyncqueuecap", "1000000");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "util/tc_epoll_server.h"
|
||||
#include "util/tc_http.h"
|
||||
#include "util/tc_option.h"
|
||||
#include "util/tc_logger.h"
|
||||
#include "util/tc_thread_pool.h"
|
||||
#include "util/tc_network_buffer.h"
|
||||
|
@ -40,21 +41,22 @@ public:
|
|||
{
|
||||
try
|
||||
{
|
||||
|
||||
g_logger.debug() << "HttpHandle::handle : " << data->ip() << ":" << data->port() << endl;
|
||||
|
||||
TC_HttpRequest request;
|
||||
|
||||
request.decode(data->buffer().data(), data->buffer().size());
|
||||
|
||||
// cout << string(data->buffer().data(), data->buffer().size()) << endl;
|
||||
// g_logger.debug() << "HttpHandle::handle : " << data->ip() << ":" << data->port() << ", " << request.getContent() << endl;
|
||||
// cout << "HttpHandle::handle : " << data->ip() << ":" << data->port() << endl;
|
||||
// cout << request.getContent() << endl;
|
||||
|
||||
TC_HttpResponse response;
|
||||
response.setResponse(200, "OK", "HttpServer");
|
||||
response.setResponse(200, "OK", request.getContent());
|
||||
|
||||
string buffer = response.encode();
|
||||
|
||||
shared_ptr<TC_EpollServer::SendContext> send = data->createSendContext();
|
||||
send->buffer()->assign(buffer.c_str(), buffer.size());
|
||||
send->buffer()->addBuffer(buffer.c_str(), buffer.size());
|
||||
|
||||
sendResponse(send);
|
||||
|
||||
|
@ -99,14 +101,22 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
|
||||
// static int g_count = 0;
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE parseEcho(TC_NetWorkBuffer&in, vector<char> &out)
|
||||
{
|
||||
TC_EpollServer::Connection *c = (TC_EpollServer::Connection *)in.getConnection();
|
||||
cout << c->getIp() << endl;
|
||||
|
||||
// DEBUG_COST("parseEcho1");
|
||||
|
||||
// TC_EpollServer::Connection *c = (TC_EpollServer::Connection *)in.getConnection();
|
||||
// cout << c->getIp() << endl;
|
||||
try
|
||||
{
|
||||
out = in.getBuffers();
|
||||
in.clearBuffers();
|
||||
// DEBUG_COST("parseEcho");
|
||||
|
||||
return TC_NetWorkBuffer::PACKET_FULL;
|
||||
}
|
||||
catch (exception &ex)
|
||||
|
@ -122,6 +132,7 @@ class SocketHandle : public TC_EpollServer::Handle
|
|||
{
|
||||
public:
|
||||
|
||||
int _count = 0;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
|
@ -138,10 +149,11 @@ public:
|
|||
{
|
||||
try
|
||||
{
|
||||
cout << "SocketHandle::handle : " << data->ip() << ":" << data->port() << endl;
|
||||
// DEBUG_COST("handle");
|
||||
|
||||
// cout << "SocketHandle::handle : " << data->ip() << ":" << data->port() << ", " << data->buffer().data() << endl;
|
||||
shared_ptr<TC_EpollServer::SendContext> send = data->createSendContext();
|
||||
send->buffer()->setBuffer(data->buffer());
|
||||
send->buffer()->setBuffer(data->buffer().data(), data->buffer().size());
|
||||
sendResponse(send);
|
||||
|
||||
}
|
||||
|
@ -160,8 +172,7 @@ public:
|
|||
{
|
||||
try
|
||||
{
|
||||
|
||||
g_logger.debug() << "SocketHandle::handleClose : " << data->ip() << ":" << data->port();
|
||||
g_logger.debug() << "SocketHandle::handleClose : " << data->ip() << ":" << data->port() << endl;
|
||||
}
|
||||
catch (exception &ex)
|
||||
{
|
||||
|
@ -182,17 +193,17 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class MyServer
|
||||
class MyServer : public TC_EpollServer
|
||||
{
|
||||
public:
|
||||
MyServer()
|
||||
{
|
||||
_epollServer = new TC_EpollServer(1);
|
||||
};
|
||||
}
|
||||
|
||||
TC_EpollServer* getEpollServer() { return this; }
|
||||
|
||||
void initialize()
|
||||
{
|
||||
cout << "initialize ok" << endl;
|
||||
g_group.start(1);
|
||||
|
||||
g_logger.init("./debug", 1024 * 1024, 10);
|
||||
|
@ -200,87 +211,99 @@ public:
|
|||
g_logger.setLogLevel(5);
|
||||
g_logger.setupThread(&g_group);
|
||||
|
||||
_epollServer->setLocalLogger(&g_logger);
|
||||
setLocalLogger(&g_logger);
|
||||
|
||||
TC_EpollServer *epollServer = this;
|
||||
|
||||
TC_Port::registerCtrlC([=]{
|
||||
epollServer->terminate();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void bindHttp(const std::string &str)
|
||||
{
|
||||
TC_EpollServer::BindAdapterPtr lsPtr = new TC_EpollServer::BindAdapter(_epollServer);
|
||||
|
||||
//设置adapter名称, 唯一
|
||||
lsPtr->setName("HttpAdapter");
|
||||
//设置绑定端口
|
||||
lsPtr->setEndpoint(str);
|
||||
//设置最大连接数
|
||||
lsPtr->setMaxConns(1024);
|
||||
//设置启动线程数
|
||||
lsPtr->setHandle<HttpHandle>(5);
|
||||
//设置协议解析器
|
||||
lsPtr->setProtocol(TC_NetWorkBuffer::parseHttp);
|
||||
//设置逻辑处理器
|
||||
g_logger.debug() << "HttpAdapter::setHandle ok" << endl;
|
||||
TC_EpollServer::BindAdapterPtr adapter = this->createBindAdapter<HttpHandle>("http", str, 1);
|
||||
adapter->setMaxConns(100000);
|
||||
adapter->setProtocol(TC_NetWorkBuffer::parseHttp);
|
||||
|
||||
//绑定对象
|
||||
_epollServer->bind(lsPtr);
|
||||
bind(adapter);
|
||||
|
||||
g_logger.debug() << "HttpAdapter::bind ok" << endl;
|
||||
g_logger.debug() << "HttpAdapter::setHandle ok" << endl;
|
||||
}
|
||||
|
||||
void bindSocket(const std::string &str)
|
||||
{
|
||||
TC_EpollServer::BindAdapterPtr lsPtr = new TC_EpollServer::BindAdapter(_epollServer);
|
||||
TC_EpollServer::BindAdapterPtr adapter = this->createBindAdapter<SocketHandle>(str, str, 5);
|
||||
|
||||
//设置adapter名称, 唯一
|
||||
lsPtr->setName("SocketAdapter");
|
||||
//设置绑定端口
|
||||
lsPtr->setEndpoint(str);
|
||||
//设置最大连接数
|
||||
lsPtr->setMaxConns(10240);
|
||||
//设置启动线程数
|
||||
lsPtr->setHandle<SocketHandle>(1);
|
||||
//设置协议解析器
|
||||
lsPtr->setProtocol(parseEcho);
|
||||
// lsPtr->enableQueueMode();
|
||||
adapter->setMaxConns(10240);
|
||||
adapter->setProtocol(parseEcho);
|
||||
|
||||
adapter->enableQueueMode();
|
||||
adapter->setQueueCapacity(1000000);
|
||||
|
||||
g_logger.debug() << "SocketAdapter::SocketHandle ok" << endl;
|
||||
|
||||
//绑定对象
|
||||
_epollServer->bind(lsPtr);
|
||||
|
||||
bind(adapter);
|
||||
|
||||
g_logger.debug() << "SocketAdapter::bind ok" << endl;
|
||||
}
|
||||
|
||||
void waitForShutdown()
|
||||
{
|
||||
_epollServer->waitForShutdown();
|
||||
}
|
||||
|
||||
protected:
|
||||
TC_EpollServer *_epollServer;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
cout << argv[0] << " --pattern=[0-3]" << endl;
|
||||
cout << "pattern 0: NET_THREAD_AND_HANDLES_THREAD" << endl;
|
||||
cout << "pattern 1: NET_THREAD_AND_HANDLES_CO" << endl;
|
||||
cout << "pattern 2: NET_HANDLES_MERGE_THREAD" << endl;
|
||||
cout << "pattern 3: NET_HANDLES_MERGE_CO" << endl;
|
||||
exit(0);
|
||||
}
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
TC_Common::ignorePipe();
|
||||
#endif
|
||||
TC_Option option;
|
||||
option.decode(argc, argv);
|
||||
|
||||
TC_EpollServer::SERVER_OPEN_COROUTINE pattern = (TC_EpollServer::SERVER_OPEN_COROUTINE)TC_Common::strto<int>(option.getValue("pattern"));
|
||||
|
||||
MyServer server;
|
||||
server.setOpenCoroutine(pattern);
|
||||
|
||||
server.initialize();
|
||||
|
||||
server.bindHttp("tcp -h 0.0.0.0 -p 8083 -t 60000");
|
||||
server.bindSocket("tcp -h 0.0.0.0 -p 8084 -t 60000");
|
||||
string ep = option.getValue("ep");
|
||||
if(ep.empty())
|
||||
{
|
||||
ep = "tcp -h 0.0.0.0 -p 8084 -t 60000";
|
||||
}
|
||||
|
||||
server.bindHttp("tcp -h 0.0.0.0 -p 8083 -t 60000");
|
||||
server.bindSocket(ep);
|
||||
server.bindSocket("udp -h 0.0.0.0 -p 8085 -t 60000");
|
||||
|
||||
// __CT__->enable(true);
|
||||
|
||||
TC_Port::registerCtrlC([&]{
|
||||
|
||||
server.getEpollServer()->terminate();
|
||||
});
|
||||
server.waitForShutdown();
|
||||
|
||||
// __CT__->output();
|
||||
// __CT__->outputAvg();
|
||||
|
||||
}
|
||||
catch (exception &ex)
|
||||
{
|
||||
cerr << "HttpServer::run ex:" << ex.what() << endl;
|
||||
cerr << "MyServer::run ex:" << ex.what() << endl;
|
||||
}
|
||||
|
||||
cout << "HttpServer::run http server thread exit." << endl;
|
||||
}
|
||||
cout << "MyServer::run server main thread exit." << endl;
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ cmake_minimum_required(VERSION 3.2)
|
|||
|
||||
project(servant)
|
||||
|
||||
if(TARS_OPENTRACKING)
|
||||
include_directories(${util_SOURCE_DIR}/include ${OPENTRACKING_INC})
|
||||
else()
|
||||
# if(TARS_OPENTRACKING)
|
||||
# include_directories(${util_SOURCE_DIR}/include ${OPENTRACKING_INC})
|
||||
# else()
|
||||
include_directories(${util_SOURCE_DIR}/include)
|
||||
endif()
|
||||
# endif()
|
||||
|
||||
#调用tars2cpp, 生成tars对应的文件
|
||||
macro(complice_tars OUT_DEPENDS_LIST HEADER INCLUDE)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,6 @@ string AdminServant::notify(const string &command, CurrentPtr current)
|
|||
{
|
||||
RemoteNotify::getInstance()->report("AdminServant::notify:" + command);
|
||||
|
||||
// return NotifyObserver::getInstance()->notify(command, current);
|
||||
return this->getApplication()->getNotifyObserver()->notify(command, current);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "util/tc_http.h"
|
||||
#include "util/tc_grpc.h"
|
||||
#include "servant/AppProtocol.h"
|
||||
#include "servant/Transceiver.h"
|
||||
// #include "servant/TC_Transceiver.h"
|
||||
#include "servant/AdapterProxy.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "tup/Tars.h"
|
||||
|
@ -31,11 +31,23 @@
|
|||
namespace tars
|
||||
{
|
||||
|
||||
class Transceiver;
|
||||
class TC_Transceiver;
|
||||
|
||||
vector<char> ProxyProtocol::tarsRequest(RequestPacket& request, Transceiver *)
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> ProxyProtocol::toBuffer(TarsOutputStream<BufferWriter> &os)
|
||||
{
|
||||
TarsOutputStream<BufferWriterVector> os;
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
buff->replaceBuffer(os.getBuffer(), os.getLength());
|
||||
os._buf = NULL;
|
||||
os._buf_len = 0;
|
||||
os._len = 0;
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> ProxyProtocol::tarsRequest(RequestPacket& request, TC_Transceiver *)
|
||||
{
|
||||
TarsOutputStream<BufferWriter> os;
|
||||
|
||||
int iHeaderLen = 0;
|
||||
|
||||
|
@ -44,32 +56,28 @@ vector<char> ProxyProtocol::tarsRequest(RequestPacket& request, Transceiver *)
|
|||
|
||||
request.writeTo(os);
|
||||
|
||||
vector<char> buff;
|
||||
assert(os.getLength() >= 4);
|
||||
|
||||
buff.swap(os.getByteBuffer());
|
||||
iHeaderLen = htonl((int)(os.getLength()));
|
||||
|
||||
assert(buff.size() >= 4);
|
||||
memcpy((void*)os.getBuffer(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
iHeaderLen = htonl((int)(buff.size()));
|
||||
|
||||
memcpy((void*)buff.data(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
return buff;
|
||||
return toBuffer(os);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<char> ProxyProtocol::http1Request(tars::RequestPacket& request, Transceiver *trans)
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> ProxyProtocol::http1Request(tars::RequestPacket& request, TC_Transceiver *trans)
|
||||
{
|
||||
shared_ptr<TC_HttpRequest> &data = *(shared_ptr<TC_HttpRequest>*)request.sBuffer.data();
|
||||
|
||||
vector<char> buffer;
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
data->encode(buffer);
|
||||
data->encode(buff);
|
||||
|
||||
data.reset();
|
||||
|
||||
return buffer;
|
||||
return buff;
|
||||
}
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http1Response(TC_NetWorkBuffer &in, ResponsePacket& rsp)
|
||||
|
@ -92,18 +100,21 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http1Response(TC_NetWorkBuffer &in,
|
|||
data = *context;
|
||||
|
||||
auto ret = TC_NetWorkBuffer::PACKET_FULL;
|
||||
if(!data->checkHeader("Connection", "keep-alive"))
|
||||
{
|
||||
// 如果非keep-alive,返回PACKET_FULL_CLOSE,外层结束连接
|
||||
if (data->checkHeader("Connection", "keep-alive") || (data->getVersion() == "HTTP/1.1" && !data->hasHeader("Connection")))
|
||||
{
|
||||
ret = TC_NetWorkBuffer::PACKET_FULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = TC_NetWorkBuffer::PACKET_FULL_CLOSE;
|
||||
}
|
||||
}
|
||||
|
||||
//收取到完整的包, 把当前包释放掉, 下次新包来会新建context
|
||||
(*context) = NULL;
|
||||
delete context;
|
||||
in.setContextData(NULL);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
return TC_NetWorkBuffer::PACKET_LESS;
|
||||
|
@ -114,14 +125,14 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http1Response(TC_NetWorkBuffer &in,
|
|||
#if TARS_HTTP2
|
||||
|
||||
// ENCODE function, called by network thread
|
||||
vector<char> ProxyProtocol::http2Request(RequestPacket& request, Transceiver *trans)
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> ProxyProtocol::http2Request(RequestPacket& request, TC_Transceiver *trans)
|
||||
{
|
||||
TC_Http2Client* session = (TC_Http2Client*)trans->getSendBuffer()->getContextData();
|
||||
TC_Http2Client* session = (TC_Http2Client*)trans->getSendBuffer().getContextData();
|
||||
if(session == NULL)
|
||||
{
|
||||
session = new TC_Http2Client();
|
||||
|
||||
trans->getSendBuffer()->setContextData(session, [=](TC_NetWorkBuffer*nb){ delete session; });
|
||||
trans->getSendBuffer().setContextData(session, [=](TC_NetWorkBuffer*){delete session;});
|
||||
|
||||
session->settings(3000);
|
||||
}
|
||||
|
@ -133,23 +144,25 @@ vector<char> ProxyProtocol::http2Request(RequestPacket& request, Transceiver *tr
|
|||
//这里把智能指针释放一次
|
||||
(*data).reset();
|
||||
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
if (request.iRequestId < 0)
|
||||
{
|
||||
TLOGERROR("http2Request::Fatal submit error: " << session->getErrMsg() << endl);
|
||||
return vector<char>();
|
||||
return buff;
|
||||
}
|
||||
|
||||
// cout << "http2Request id:" << request.iRequestId << endl;
|
||||
|
||||
vector<char> out;
|
||||
session->swap(out);
|
||||
|
||||
return out;
|
||||
buff->addBuffer(out);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, ResponsePacket& rsp)
|
||||
{
|
||||
TC_Http2Client* session = (TC_Http2Client*)((Transceiver*)(in.getConnection()))->getSendBuffer()->getContextData();
|
||||
TC_Http2Client* session = (TC_Http2Client*)((TC_Transceiver*)(in.getConnection()))->getSendBuffer().getContextData();
|
||||
|
||||
pair<int, shared_ptr<TC_HttpResponse>> out;
|
||||
TC_NetWorkBuffer::PACKET_TYPE flag = session->parseResponse(in, out);
|
||||
|
@ -169,24 +182,27 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in,
|
|||
|
||||
|
||||
// ENCODE function, called by network thread
|
||||
vector<char> ProxyProtocol::grpcRequest(RequestPacket& request, Transceiver *trans)
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> ProxyProtocol::grpcRequest(RequestPacket& request, TC_Transceiver *trans)
|
||||
{
|
||||
TC_GrpcClient* session = (TC_GrpcClient*)trans->getSendBuffer()->getContextData();
|
||||
TC_GrpcClient* session = (TC_GrpcClient*)trans->getSendBuffer().getContextData();
|
||||
if(session == NULL)
|
||||
{
|
||||
session = new TC_GrpcClient();
|
||||
|
||||
trans->getSendBuffer()->setContextData(session, [=](TC_NetWorkBuffer*nb){ delete session; });
|
||||
trans->getSendBuffer().setContextData(session, [=](TC_NetWorkBuffer*){ delete session; });
|
||||
|
||||
session->settings(3000);
|
||||
}
|
||||
|
||||
if (session->buffer().size() != 0) {
|
||||
//直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
trans->getSendBuffer()->addBuffer(session->buffer());
|
||||
auto data = trans->getSendBuffer()->getBufferPointer();
|
||||
int iRet = trans->send(data.first, (uint32_t) data.second, 0);
|
||||
trans->getSendBuffer()->moveHeader(iRet);
|
||||
trans->getSendBuffer().addBuffer(session->buffer());
|
||||
|
||||
trans->doRequest();
|
||||
|
||||
// auto data = trans->getSendBuffer().getBufferPointer();
|
||||
// int iRet = trans->send(data.first, (uint32_t) data.second, 0);
|
||||
// trans->getSendBuffer().moveHeader(iRet);
|
||||
session->buffer().clear();
|
||||
}
|
||||
|
||||
|
@ -197,10 +213,12 @@ vector<char> ProxyProtocol::grpcRequest(RequestPacket& request, Transceiver *tra
|
|||
//这里把智能指针释放一次
|
||||
(*data).reset();
|
||||
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
if (request.iRequestId < 0)
|
||||
{
|
||||
TLOGERROR("http2Request::Fatal submit error: " << session->getErrMsg() << endl);
|
||||
return vector<char>();
|
||||
return buff;
|
||||
}
|
||||
|
||||
// cout << "http2Request id:" << request.iRequestId << endl;
|
||||
|
@ -208,12 +226,14 @@ vector<char> ProxyProtocol::grpcRequest(RequestPacket& request, Transceiver *tra
|
|||
vector<char> out;
|
||||
session->swap(out);
|
||||
|
||||
return out;
|
||||
buff->addBuffer(out);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::grpcResponse(TC_NetWorkBuffer &in, ResponsePacket& rsp)
|
||||
{
|
||||
TC_GrpcClient* session = (TC_GrpcClient*)((Transceiver*)(in.getConnection()))->getSendBuffer()->getContextData();
|
||||
TC_GrpcClient* session = (TC_GrpcClient*)((TC_Transceiver*)(in.getConnection()))->getSendBuffer().getContextData();
|
||||
|
||||
pair<int, shared_ptr<TC_HttpResponse>> out;
|
||||
TC_NetWorkBuffer::PACKET_TYPE flag = session->parseResponse(in, out);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include "util/tc_option.h"
|
||||
#include "util/tc_common.h"
|
||||
#include "servant/KeepAliveNodeF.h"
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include "servant/AppCache.h"
|
||||
#include "servant/NotifyObserver.h"
|
||||
#include "servant/AuthLogic.h"
|
||||
#include "servant/CommunicatorFactory.h"
|
||||
|
||||
#include <signal.h>
|
||||
#if TARGET_PLATFORM_LINUX
|
||||
|
@ -40,28 +41,16 @@
|
|||
#include "util/tc_openssl.h"
|
||||
#endif
|
||||
|
||||
static TC_RollLogger __out__;
|
||||
|
||||
#define NOTIFY_AND_WAIT(msg) { \
|
||||
RemoteNotify::getInstance()->report(msg); \
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); \
|
||||
}
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
//static void sighandler( int sig_no )
|
||||
//{
|
||||
// TLOGERROR("[TARS][sighandler] sig_no :" << sig_no << endl);
|
||||
//
|
||||
// Application::terminate();
|
||||
//}
|
||||
//#else
|
||||
//static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
|
||||
//{
|
||||
// TLOGERROR("[TARS][sighandler] dwCtrlType :" << dwCtrlType << endl);
|
||||
// Application::terminate();
|
||||
// ExitProcess(0);
|
||||
// return TRUE;
|
||||
//}
|
||||
//#endif
|
||||
|
||||
|
||||
std::string ServerConfig::TarsPath; //服务路径
|
||||
std::string ServerConfig::Application; //应用名称
|
||||
std::string ServerConfig::ServerName; //服务名称,一个服务名称含一个或多个服务标识
|
||||
|
@ -78,17 +67,18 @@ int ServerConfig::LogSize; //log大小(字节)
|
|||
int ServerConfig::LogNum; //log个数()
|
||||
std::string ServerConfig::LogLevel; //log日志级别
|
||||
std::string ServerConfig::ConfigFile; //框架配置文件路径
|
||||
int ServerConfig::ReportFlow = 1; //是否服务端上报所有接口stat流量 0不上报 1上报 (用于非taf协议服务流量统计)
|
||||
int ServerConfig::ReportFlow = 1; //是否服务端上报所有接口stat流量 0不上报 1上报 (用于非tars协议服务流量统计)
|
||||
int ServerConfig::IsCheckSet = 1; //是否对按照set规则调用进行合法性检查 0,不检查,1检查
|
||||
bool ServerConfig::OpenCoroutine = false; //是否启用协程处理方式
|
||||
int ServerConfig::OpenCoroutine = 0; //是否启用协程处理方式
|
||||
size_t ServerConfig::CoroutineMemSize; //协程占用内存空间的最大大小
|
||||
uint32_t ServerConfig::CoroutineStackSize; //每个协程的栈大小(默认128k)
|
||||
bool ServerConfig::ManualListen = false; //手工启动监听端口
|
||||
bool ServerConfig::MergeNetImp = false; //合并网络和处理线程
|
||||
//bool ServerConfig::MergeNetImp = false; //合并网络和处理线程
|
||||
int ServerConfig::NetThread = 1; //servernet thread
|
||||
bool ServerConfig::CloseCout = true;
|
||||
int ServerConfig::BackPacketLimit = 0;
|
||||
int ServerConfig::BackPacketMin = 1024;
|
||||
//int ServerConfig::Pattern = 0;
|
||||
|
||||
#if TARS_SSL
|
||||
std::string ServerConfig::CA;
|
||||
|
@ -113,22 +103,26 @@ PropertyReportPtr g_pReportRspQueue;
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
Application::Application()
|
||||
{
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||
#endif
|
||||
_servantHelper = std::make_shared<ServantHelperManager>();
|
||||
|
||||
_notifyObserver = std::make_shared<NotifyObserver>();
|
||||
|
||||
setNotifyObserver(_notifyObserver);
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||
#endif
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
terminate();
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
if(_epollServer)
|
||||
{
|
||||
_epollServer->terminate();
|
||||
_epollServer = NULL;
|
||||
}
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
@ -137,16 +131,6 @@ string Application::getTarsVersion()
|
|||
{
|
||||
return TARS_VERSION;
|
||||
}
|
||||
//
|
||||
//TC_Config& Application::getConfig()
|
||||
//{
|
||||
// return _conf;
|
||||
//}
|
||||
//
|
||||
//TC_EpollServerPtr& Application::getEpollServer()
|
||||
//{
|
||||
// return _epollServer;
|
||||
//}
|
||||
|
||||
CommunicatorPtr& Application::getCommunicator()
|
||||
{
|
||||
|
@ -155,8 +139,6 @@ CommunicatorPtr& Application::getCommunicator()
|
|||
|
||||
void reportRspQueue(TC_EpollServer *epollServer)
|
||||
{
|
||||
// TLOGDEBUG("Application::reportRspQueue" << endl);
|
||||
|
||||
if (!g_pReportRspQueue)
|
||||
return;
|
||||
|
||||
|
@ -197,18 +179,34 @@ void Application::manualListen()
|
|||
|
||||
void Application::waitForShutdown()
|
||||
{
|
||||
assert(_epollServer);
|
||||
|
||||
_epollServer->setCallbackFunctor(reportRspQueue);
|
||||
|
||||
_epollServer->setHeartBeatFunctor(heartBeatFunc);
|
||||
|
||||
_epollServer->waitForShutdown();
|
||||
_epollServer->setDestroyAppFunctor([&](TC_EpollServer *epollServer){
|
||||
|
||||
destroyApp();
|
||||
this->destroyApp();
|
||||
|
||||
RemoteNotify::getInstance()->report("stop");
|
||||
NOTIFY_AND_WAIT("stop");
|
||||
});
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); //稍微休息一下, 让当前处理包能够回复
|
||||
_epollServer->waitForShutdown();
|
||||
|
||||
TC_Port::unregisterCtrlC(_ctrlCId);
|
||||
TC_Port::unregisterTerm(_termId);
|
||||
|
||||
_epollServer = NULL;
|
||||
|
||||
}
|
||||
|
||||
void Application::waitForReady()
|
||||
{
|
||||
if(_epollServer)
|
||||
{
|
||||
_epollServer->waitForReady();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::terminate()
|
||||
|
@ -303,6 +301,7 @@ bool Application::cmdCloseCoreDump(const string& command, const string& params,
|
|||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Application::cmdSetLogLevel(const string& command, const string& params, string& result)
|
||||
{
|
||||
TLOGTARS("Application::cmdSetLogLevel:" << command << " " << params << endl);
|
||||
|
@ -363,29 +362,29 @@ bool Application::cmdEnableDayLog(const string& command, const string& params, s
|
|||
string sFile;
|
||||
|
||||
|
||||
if(nNum == 2)
|
||||
if (nNum == 2)
|
||||
{
|
||||
bEnable = (vParams[1] == "true")?true:false;
|
||||
bEnable = (vParams[1] == "true") ? true : false;
|
||||
sFile = "";
|
||||
result = "set " + vParams[0] + " " + vParams[1] + " ok";
|
||||
}
|
||||
else if(nNum == 3)
|
||||
else if (nNum == 3)
|
||||
{
|
||||
bEnable = (vParams[2] == "true")?true:false;
|
||||
bEnable = (vParams[2] == "true") ? true : false;
|
||||
sFile = vParams[1];
|
||||
result = "set " + vParams[0] + " " + vParams[1] + " "+vParams[2] + " ok";
|
||||
result = "set " + vParams[0] + " " + vParams[1] + " " + vParams[2] + " ok";
|
||||
}
|
||||
|
||||
|
||||
if(vParams[0] == "local")
|
||||
if (vParams[0] == "local")
|
||||
{
|
||||
RemoteTimeLogger::getInstance()->enableLocal(sFile,bEnable);
|
||||
RemoteTimeLogger::getInstance()->enableLocal(sFile, bEnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(vParams[0] == "remote")
|
||||
if (vParams[0] == "remote")
|
||||
{
|
||||
RemoteTimeLogger::getInstance()->enableRemote(sFile,bEnable);
|
||||
RemoteTimeLogger::getInstance()->enableRemote(sFile, bEnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -400,7 +399,7 @@ bool Application::cmdLoadConfig(const string& command, const string& params, str
|
|||
|
||||
string filename = TC_Common::trim(params);
|
||||
|
||||
if (RemoteConfig::getInstance()->addConfig(filename, result,false))
|
||||
if (RemoteConfig::getInstance()->addConfig(filename, result, false))
|
||||
{
|
||||
RemoteNotify::getInstance()->report(result);
|
||||
|
||||
|
@ -536,7 +535,7 @@ bool Application::cmdViewAdminCommands(const string& command, const string& para
|
|||
{
|
||||
TLOGTARS("Application::cmdViewAdminCommands:" << command << " " << params << endl);
|
||||
|
||||
result =result + _notifyObserver->viewRegisterCommand();
|
||||
result = result + _notifyObserver->viewRegisterCommand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -545,9 +544,9 @@ bool Application::cmdSetDyeing(const string& command, const string& params, stri
|
|||
{
|
||||
vector<string> vDyeingParams = TC_Common::sepstr<string>(params, " ");
|
||||
|
||||
if(vDyeingParams.size() == 2 || vDyeingParams.size() == 3)
|
||||
if (vDyeingParams.size() == 2 || vDyeingParams.size() == 3)
|
||||
{
|
||||
_servantHelper->setDyeing(vDyeingParams[0], vDyeingParams[1], vDyeingParams.size() == 3 ? vDyeingParams[2] : "");
|
||||
_servantHelper->setDyeing(vDyeingParams[0], vDyeingParams[1], vDyeingParams.size() == 3 ? vDyeingParams[2] : "");
|
||||
|
||||
result = "DyeingKey=" + vDyeingParams[0] + "\r\n" +
|
||||
"DyeingServant=" + vDyeingParams[1] + "\r\n" +
|
||||
|
@ -566,13 +565,13 @@ bool Application::cmdCloseCout(const string& command, const string& params, stri
|
|||
|
||||
string s = TC_Common::lower(TC_Common::trim(params));
|
||||
|
||||
if(s == "yes")
|
||||
if (s == "yes")
|
||||
{
|
||||
AppCache::getInstance()->set("closeCout","1");
|
||||
AppCache::getInstance()->set("closeCout", "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
AppCache::getInstance()->set("closeCout","0");
|
||||
AppCache::getInstance()->set("closeCout", "0");
|
||||
}
|
||||
|
||||
result = "set closeCout [" + s + "] ok";
|
||||
|
@ -582,13 +581,15 @@ bool Application::cmdCloseCout(const string& command, const string& params, stri
|
|||
|
||||
bool Application::cmdReloadLocator(const string& command, const string& params, string& result)
|
||||
{
|
||||
TLOGTARS("Application::cmdReloadLocator:" << command << " " << params << endl);
|
||||
TLOGDEBUG("Application::cmdReloadLocator:" << command << " " << params << endl);
|
||||
|
||||
string sPara = TC_Common::lower(TC_Common::trim(params));
|
||||
|
||||
bool bSucc(true);
|
||||
if (sPara == "reload")
|
||||
{
|
||||
TLOGDEBUG(__FUNCTION__ << "|" << __LINE__ << "|conf file:" << ServerConfig::ConfigFile << endl);
|
||||
|
||||
TC_Config reloadConf;
|
||||
|
||||
reloadConf.parseFile(ServerConfig::ConfigFile);
|
||||
|
@ -693,6 +694,7 @@ void Application::main(int argc, char *argv[])
|
|||
{
|
||||
TC_Option op;
|
||||
op.decode(argc, argv);
|
||||
|
||||
main(op);
|
||||
}
|
||||
|
||||
|
@ -701,14 +703,14 @@ void Application::main(const TC_Option &option)
|
|||
//直接输出编译的TARS版本
|
||||
if(option.hasParam("version"))
|
||||
{
|
||||
cout << "TARS:" << TARS_VERSION << endl;
|
||||
__out__.debug() << "TARS:" << TARS_VERSION << endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//加载配置文件
|
||||
ServerConfig::ConfigFile = option.getValue("config");
|
||||
|
||||
if(ServerConfig::ConfigFile == "")
|
||||
if (ServerConfig::ConfigFile == "")
|
||||
{
|
||||
cerr << "start server with config, for example: exe --config=config.conf" << endl;
|
||||
|
||||
|
@ -722,6 +724,7 @@ void Application::main(const TC_Option &option)
|
|||
|
||||
void Application::main(const string &config)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
|
@ -742,12 +745,16 @@ void Application::main(const string &config)
|
|||
//绑定对象和端口
|
||||
bindAdapter(adapters);
|
||||
|
||||
stringstream os;
|
||||
|
||||
//输出所有adapter
|
||||
outAllAdapter(cout);
|
||||
outAllAdapter(os);
|
||||
|
||||
cout << "\n" << TC_Common::outfill("[initialize server] ", '.') << " [Done]" << endl;
|
||||
__out__.info() << os.str();
|
||||
|
||||
cout << OUT_LINE_LONG << endl;
|
||||
__out__.info() << "\n" << TC_Common::outfill("[initialize server] ", '.') << " [Done]" << endl;
|
||||
|
||||
__out__.info() << OUT_LINE_LONG << endl;
|
||||
|
||||
{
|
||||
bool initing = true;
|
||||
|
@ -756,36 +763,41 @@ void Application::main(const string &config)
|
|||
|
||||
std::thread keepActiving([&]
|
||||
{
|
||||
do {
|
||||
do
|
||||
{
|
||||
//发送心跳给node, 表示正在启动
|
||||
TARS_KEEPACTIVING;
|
||||
|
||||
//等待initialize初始化完毕
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
cond.wait_for(lock, std::chrono::seconds(2));
|
||||
cond.wait_for(lock, std::chrono::seconds(5), [&](){
|
||||
return !initing;
|
||||
});
|
||||
|
||||
}while(initing);
|
||||
|
||||
}while(initing);
|
||||
});
|
||||
//捕捉初始化可能的异常
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
TC_Common::msleep(100);
|
||||
//业务应用的初始化
|
||||
initialize();
|
||||
initing = false;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
initing = false;
|
||||
cond.notify_all();
|
||||
}
|
||||
|
||||
keepActiving.join();
|
||||
}
|
||||
}
|
||||
catch (exception & ex)
|
||||
{
|
||||
keepActiving.detach();
|
||||
RemoteNotify::getInstance()->report("exit: " + string(ex.what()));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); //稍微休息一下, 让当前处理包能够回复
|
||||
|
||||
cout << "[init exception]:" << ex.what() << endl;
|
||||
NOTIFY_AND_WAIT("exit: " + string(ex.what()));
|
||||
|
||||
__out__.error() << "[init exception]:" << ex.what() << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
@ -842,24 +854,13 @@ void Application::main(const string &config)
|
|||
RemoteNotify::getInstance()->report("restart");
|
||||
|
||||
//ctrl + c能够完美结束服务
|
||||
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
// std::thread th1(signal, SIGINT, sighandler);
|
||||
// th1.detach();
|
||||
// //k8s pod完美退出
|
||||
// std::thread th2(signal, SIGTERM, sighandler);
|
||||
// th2.detach();
|
||||
//#else
|
||||
// std::thread th([] {SetConsoleCtrlHandler(HandlerRoutine, TRUE); });
|
||||
// th.detach();
|
||||
//#endif
|
||||
//#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
TC_Port::registerCtrlC([=]{
|
||||
this->terminate();
|
||||
_ctrlCId = TC_Port::registerCtrlC([=]{
|
||||
this->terminate();
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
ExitProcess(0);
|
||||
ExitProcess(0);
|
||||
#endif
|
||||
});
|
||||
TC_Port::registerTerm([=]{
|
||||
});
|
||||
_termId = TC_Port::registerTerm([=]{
|
||||
this->terminate();
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
ExitProcess(0);
|
||||
|
@ -871,83 +872,87 @@ void Application::main(const string &config)
|
|||
{
|
||||
// 重定向stdin、stdout、stderr
|
||||
int fd = open("/dev/null", O_RDWR );
|
||||
if(fd != -1)
|
||||
if (fd != -1)
|
||||
{
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
catch (exception &ex)
|
||||
{
|
||||
cout << "[main exception]:" << ex.what() << endl;
|
||||
__out__.error() << "[main exception]:" << ex.what() << endl;
|
||||
|
||||
RemoteNotify::getInstance()->report("exit: " + string(ex.what()));
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); //稍微休息一下, 让当前处理包能够回复
|
||||
|
||||
exit(-1);
|
||||
NOTIFY_AND_WAIT("exit: " + string(ex.what()));
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//初始化完毕后, 日志再修改为异步
|
||||
//初始化完毕后, 日志再修改为异步
|
||||
LocalRollLogger::getInstance()->sync(false);
|
||||
}
|
||||
|
||||
|
||||
void Application::parseConfig(const string &config)
|
||||
{
|
||||
_conf.parseString(config);
|
||||
|
||||
__out__.setLogLevel(_conf.get("/tars/application/server<start_output>", "DEBUG"));
|
||||
|
||||
onParseConfig(_conf);
|
||||
}
|
||||
|
||||
TC_EpollServer::BindAdapter::EOrder Application::parseOrder(const string &s)
|
||||
{
|
||||
vector<string> vtOrder = TC_Common::sepstr<string>(s,";, \t", false);
|
||||
vector<string> vtOrder = TC_Common::sepstr<string>(s, ";, \t", false);
|
||||
|
||||
if(vtOrder.size() != 2)
|
||||
if (vtOrder.size() != 2)
|
||||
{
|
||||
cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'."<< endl;
|
||||
cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'." << endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
if((TC_Common::lower(vtOrder[0]) == "allow")&&(TC_Common::lower(vtOrder[1]) == "deny"))
|
||||
if ((TC_Common::lower(vtOrder[0]) == "allow") && (TC_Common::lower(vtOrder[1]) == "deny"))
|
||||
{
|
||||
return TC_EpollServer::BindAdapter::ALLOW_DENY;
|
||||
}
|
||||
if((TC_Common::lower(vtOrder[0]) == "deny")&&(TC_Common::lower(vtOrder[1]) == "allow"))
|
||||
if ((TC_Common::lower(vtOrder[0]) == "deny") && (TC_Common::lower(vtOrder[1]) == "allow"))
|
||||
{
|
||||
return TC_EpollServer::BindAdapter::DENY_ALLOW;
|
||||
return TC_EpollServer::BindAdapter::DENY_ALLOW;
|
||||
}
|
||||
|
||||
cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'."<< endl;
|
||||
cerr << "invalid order '" << TC_Common::tostr(vtOrder) << "'." << endl;
|
||||
|
||||
exit(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Application::initializeClient()
|
||||
{
|
||||
cout << "\n" << OUT_LINE_LONG << endl;
|
||||
__out__.info() << "\n" << OUT_LINE_LONG << endl;
|
||||
|
||||
//初始化通信器
|
||||
_communicator = CommunicatorFactory::getInstance()->getCommunicator(_conf);
|
||||
|
||||
cout << TC_Common::outfill("[proxy config]:") << endl;
|
||||
__out__.info() << TC_Common::outfill("[proxy config]:") << endl;
|
||||
|
||||
//输出
|
||||
outClient(cout);
|
||||
stringstream os;
|
||||
outClient(os);
|
||||
|
||||
__out__.info() << os.str();
|
||||
}
|
||||
|
||||
void Application::outClient(ostream &os)
|
||||
{
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[load client]:") << endl;
|
||||
os << OUT_LINE << "\n" << TC_Common::outfill("[load client]:") << endl;
|
||||
|
||||
os << TC_Common::outfill("locator") << _communicator->getProperty("locator") << endl;
|
||||
os << TC_Common::outfill("sync-invoke-timeout") << _communicator->getProperty("sync-invoke-timeout") << endl;
|
||||
|
@ -967,7 +972,7 @@ void Application::outClient(ostream &os)
|
|||
|
||||
string Application::toDefault(const string &s, const string &sDefault)
|
||||
{
|
||||
if(s.empty())
|
||||
if (s.empty())
|
||||
{
|
||||
return sDefault;
|
||||
}
|
||||
|
@ -1006,17 +1011,17 @@ void Application::onAccept(TC_EpollServer::Connection* cPtr)
|
|||
}
|
||||
}
|
||||
|
||||
void Application::addServantOnClose(const string& servant, const TC_EpollServer::close_functor& cf)
|
||||
{
|
||||
string adapterName = _servantHelper->getServantAdapter(servant);
|
||||
|
||||
if (adapterName.empty())
|
||||
{
|
||||
throw runtime_error("setServantOnClose fail, no found adapter for servant:" + servant);
|
||||
}
|
||||
|
||||
getEpollServer()->getBindAdapter(adapterName)->setOnClose(cf);
|
||||
}
|
||||
//void Application::addServantOnClose(const string& servant, const TC_EpollServer::close_functor& cf)
|
||||
//{
|
||||
// string adapterName = _servantHelper->getServantAdapter(servant);
|
||||
//
|
||||
// if (adapterName.empty())
|
||||
// {
|
||||
// throw runtime_error("setServantOnClose fail, no found adapter for servant:" + servant);
|
||||
// }
|
||||
//
|
||||
// getEpollServer()->getBindAdapter(adapterName)->setOnClose(cf);
|
||||
//}
|
||||
|
||||
void Application::outServer(ostream &os)
|
||||
{
|
||||
|
@ -1040,17 +1045,17 @@ void Application::outServer(ostream &os)
|
|||
os << TC_Common::outfill("CloseCout(closecout)") << ServerConfig::CloseCout << endl;
|
||||
os << TC_Common::outfill("NetThread(netthread)") << ServerConfig::NetThread << endl;
|
||||
os << TC_Common::outfill("ManualListen(manuallisten)") << ServerConfig::ManualListen << endl;
|
||||
os << TC_Common::outfill("MergeNetImp(mergenetimp)") << ServerConfig::MergeNetImp << endl;
|
||||
// os << TC_Common::outfill("MergeNetImp(mergenetimp)") << ServerConfig::MergeNetImp << endl;
|
||||
os << TC_Common::outfill("ReportFlow(reportflow)") << ServerConfig::ReportFlow<< endl;
|
||||
os << TC_Common::outfill("BackPacketLimit(backpacketlimit)") << ServerConfig::BackPacketLimit<< endl;
|
||||
os << TC_Common::outfill("BackPacketMin(backpacketmin)") << ServerConfig::BackPacketMin<< endl;
|
||||
|
||||
#if TARS_SSL
|
||||
cout << TC_Common::outfill("Ca(ca)") << ServerConfig::CA << endl;
|
||||
cout << TC_Common::outfill("Cert(cert)") << ServerConfig::Cert << endl;
|
||||
cout << TC_Common::outfill("Key(key)") << ServerConfig::Key << endl;
|
||||
cout << TC_Common::outfill("VerifyClient(verifyclient)") << ServerConfig::VerifyClient << endl;
|
||||
cout << TC_Common::outfill("Ciphers(ciphers)") << ServerConfig::Ciphers << endl;
|
||||
os << TC_Common::outfill("Ca(ca)") << ServerConfig::CA << endl;
|
||||
os << TC_Common::outfill("Cert(cert)") << ServerConfig::Cert << endl;
|
||||
os << TC_Common::outfill("Key(key)") << ServerConfig::Key << endl;
|
||||
os << TC_Common::outfill("VerifyClient(verifyclient)") << ServerConfig::VerifyClient << endl;
|
||||
os << TC_Common::outfill("Ciphers(ciphers)") << ServerConfig::Ciphers << endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -1058,7 +1063,7 @@ void Application::outServer(ostream &os)
|
|||
|
||||
void Application::initializeServer()
|
||||
{
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[server config]:") << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[server config]:") << endl;
|
||||
|
||||
ServerConfig::Application = toDefault(_conf.get("/tars/application/server<app>"), "UNKNOWN");
|
||||
|
||||
|
@ -1069,7 +1074,7 @@ void Application::initializeServer()
|
|||
{
|
||||
exe = TC_File::extractFileName(TC_File::getExePath());
|
||||
}
|
||||
catch(TC_File_Exception & ex)
|
||||
catch (TC_File_Exception & ex)
|
||||
{
|
||||
//取失败则使用ip代替进程名
|
||||
exe = _conf.get("/tars/application/server<localip>");
|
||||
|
@ -1114,11 +1119,11 @@ void Application::initializeServer()
|
|||
ServerConfig::Notify = _conf.get("/tars/application/server<notify>");
|
||||
ServerConfig::ReportFlow = _conf.get("/tars/application/server<reportflow>")=="0"?0:1;
|
||||
ServerConfig::IsCheckSet = _conf.get("/tars/application/server<checkset>","1")=="0"?0:1;
|
||||
ServerConfig::OpenCoroutine = TC_Common::strto<bool>(toDefault(_conf.get("/tars/application/server<opencoroutine>"), "0"));
|
||||
ServerConfig::OpenCoroutine = TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<opencoroutine>"), "0"));
|
||||
ServerConfig::CoroutineMemSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server<coroutinememsize>"), "1G"), 1024*1024*1024);
|
||||
ServerConfig::CoroutineStackSize= (uint32_t)TC_Common::toSize(toDefault(_conf.get("/tars/application/server<coroutinestack>"), "128K"), 1024*128);
|
||||
ServerConfig::ManualListen = _conf.get("/tars/application/server<manuallisten>", "0") == "0" ? false : true;
|
||||
ServerConfig::MergeNetImp = _conf.get("/tars/application/server<mergenetimp>", "0") == "0" ? false : true;
|
||||
// ServerConfig::MergeNetImp = _conf.get("/tars/application/server<mergenetimp>", "0") == "0" ? false : true;
|
||||
ServerConfig::NetThread = TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<netthread>"), "1"));
|
||||
ServerConfig::CloseCout = _conf.get("/tars/application/server<closecout>","1")=="0"?0:1;
|
||||
ServerConfig::BackPacketLimit = TC_Common::strto<int>(_conf.get("/tars/application/server<backpacketlimit>", "100*1024*1024"));
|
||||
|
@ -1136,7 +1141,7 @@ void Application::initializeServer()
|
|||
_ctx = TC_OpenSSL::newCtx(ServerConfig::CA, ServerConfig::Cert, ServerConfig::Key, ServerConfig::VerifyClient, ServerConfig::Ciphers);
|
||||
|
||||
if (!_ctx) {
|
||||
TLOGERROR("[TARS]load server ssl error, ca:" << ServerConfig::CA << endl);
|
||||
TLOGERROR("[load server ssl error, ca:" << ServerConfig::CA << endl);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
@ -1162,43 +1167,53 @@ void Application::initializeServer()
|
|||
|
||||
onServerConfig();
|
||||
|
||||
ostringstream os;
|
||||
//输出信息
|
||||
outServer(cout);
|
||||
outServer(os);
|
||||
|
||||
if (ServerConfig::NetThread < 1)
|
||||
__out__.info() << os.str();
|
||||
|
||||
if (ServerConfig::NetThread < 1)
|
||||
{
|
||||
ServerConfig::NetThread = 1;
|
||||
cout << OUT_LINE << "\nwarning:netThreadNum < 1." << endl;
|
||||
__out__.info() << OUT_LINE << "\nwarning:netThreadNum < 1." << endl;
|
||||
}
|
||||
|
||||
//网络线程的配置数目不能15个
|
||||
if (ServerConfig::NetThread > 15)
|
||||
{
|
||||
ServerConfig::NetThread = 15;
|
||||
cout << OUT_LINE << "\nwarning:netThreadNum > 15." << endl;
|
||||
__out__.info() << OUT_LINE << "\nwarning:netThreadNum > 15." << endl;
|
||||
}
|
||||
|
||||
_epollServer = new TC_EpollServer(ServerConfig::NetThread);
|
||||
if(ServerConfig::CoroutineMemSize/ServerConfig::CoroutineStackSize <= 0)
|
||||
{
|
||||
__out__.error() << OUT_LINE << "\nerror:coroutine paramter error: coroutinememsize/coroutinestack <= 0!." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
_epollServer = new TC_EpollServer();
|
||||
|
||||
_epollServer->setThreadNum(ServerConfig::NetThread);
|
||||
_epollServer->setOpenCoroutine((TC_EpollServer::SERVER_OPEN_COROUTINE)ServerConfig::OpenCoroutine);
|
||||
_epollServer->setCoroutineStack(ServerConfig::CoroutineMemSize/ServerConfig::CoroutineStackSize, ServerConfig::CoroutineStackSize);
|
||||
|
||||
_epollServer->setOnAccept(std::bind(&Application::onAccept, this, std::placeholders::_1));
|
||||
|
||||
//初始化服务是否对空链接进行超时检查
|
||||
bool bEnable = (_conf.get("/tars/application/server<emptyconcheck>","0")=="1")?true:false;
|
||||
// bool bEnable = (_conf.get("/tars/application/server<emptyconcheck>","0")=="1")?true:false;
|
||||
|
||||
_epollServer->enAntiEmptyConnAttack(bEnable);
|
||||
_epollServer->setEmptyConnTimeout(TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<emptyconntimeout>"), "3")));
|
||||
// _epollServer->enAntiEmptyConnAttack(bEnable);
|
||||
_epollServer->setEmptyConnTimeout(TC_Common::strto<int>(toDefault(_conf.get("/tars/application/server<emptyconntimeout>"), "0")));
|
||||
|
||||
//合并线程
|
||||
_epollServer->setMergeHandleNetThread(ServerConfig::MergeNetImp);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化本地文件cache
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set file cache ]") << "OK" << endl;
|
||||
AppCache::getInstance()->setCacheInfo(ServerConfig::DataPath+ServerConfig::ServerName+".tarsdat",0);
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set file cache ]") << "OK" << endl;
|
||||
AppCache::getInstance()->setCacheInfo(ServerConfig::DataPath + ServerConfig::ServerName + ".tarsdat", 0);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化本地Log
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set roll logger] ") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set roll logger] ") << "OK" << endl;
|
||||
LocalRollLogger::getInstance()->setLogInfo(ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath, ServerConfig::LogSize, ServerConfig::LogNum, _communicator, ServerConfig::Log);
|
||||
_epollServer->setLocalLogger(LocalRollLogger::getInstance()->logger());
|
||||
|
||||
|
@ -1218,40 +1233,40 @@ void Application::initializeServer()
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化到LogServer代理
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set time logger] ") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set time logger] ") << "OK" << endl;
|
||||
bool bLogStatReport = (_conf.get("/tars/application/server<logstatreport>", "0") == "1") ? true : false;
|
||||
RemoteTimeLogger::getInstance()->setLogInfo(_communicator, ServerConfig::Log, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath, setDivision(), bLogStatReport);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化到配置中心代理
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set remote config] ") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set remote config] ") << "OK" << endl;
|
||||
RemoteConfig::getInstance()->setConfigInfo(_communicator, ServerConfig::Config, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::BasePath,setDivision());
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化到信息中心代理
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set remote notify] ") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set remote notify] ") << "OK" << endl;
|
||||
RemoteNotify::getInstance()->setNotifyInfo(_communicator, ServerConfig::Notify, ServerConfig::Application, ServerConfig::ServerName, setDivision(), ServerConfig::LocalIp);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化到Node的代理
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set node proxy]") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set node proxy]") << "OK" << endl;
|
||||
KeepAliveNodeFHelper::getInstance()->setNodeInfo(_communicator, ServerConfig::Node, ServerConfig::Application, ServerConfig::ServerName);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//初始化管理对象
|
||||
cout << OUT_LINE << "\n" << TC_Common::outfill("[set admin adapter]") << "OK" << endl;
|
||||
__out__.info() << OUT_LINE << "\n" << TC_Common::outfill("[set admin adapter]") << "OK" << endl;
|
||||
|
||||
if(!ServerConfig::Local.empty())
|
||||
if (!ServerConfig::Local.empty())
|
||||
{
|
||||
_servantHelper->addServant<AdminServant>("AdminObj", this);
|
||||
|
||||
_servantHelper->setAdapterServant("AdminAdapter", "AdminObj");
|
||||
string adminAdapter = "AdminAdapter";
|
||||
|
||||
TC_EpollServer::BindAdapterPtr lsPtr = new TC_EpollServer::BindAdapter(_epollServer.get());
|
||||
_servantHelper->setAdapterServant(adminAdapter, "AdminObj");
|
||||
|
||||
setAdapter(lsPtr, "AdminAdapter");
|
||||
TC_EpollServer::BindAdapterPtr lsPtr = _epollServer->createBindAdapter<ServantHandle>(adminAdapter, ServerConfig::Local, 1, this);
|
||||
|
||||
lsPtr->setEndpoint(ServerConfig::Local);
|
||||
setAdapter(lsPtr, adminAdapter);
|
||||
|
||||
lsPtr->setMaxConns(TC_EpollServer::BindAdapter::DEFAULT_MAX_CONN);
|
||||
|
||||
|
@ -1263,9 +1278,8 @@ void Application::initializeServer()
|
|||
|
||||
lsPtr->setProtocol(AppProtocol::parse);
|
||||
|
||||
lsPtr->setHandle<ServantHandle>(1, this);
|
||||
|
||||
_epollServer->bind(lsPtr);
|
||||
|
||||
}
|
||||
|
||||
//队列取平均值
|
||||
|
@ -1284,18 +1298,14 @@ void Application::initializeServer()
|
|||
|
||||
void Application::setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name)
|
||||
{
|
||||
adapter->setName(name);
|
||||
|
||||
// 设置该obj的鉴权账号密码,只要一组就够了
|
||||
{
|
||||
std::string accKey = _conf.get("/tars/application/server/" + name + "<accesskey>");
|
||||
std::string secretKey = _conf.get("/tars/application/server/" + name + "<secretkey>");
|
||||
|
||||
if (!accKey.empty())
|
||||
adapter->setAkSk(accKey, secretKey);
|
||||
|
||||
// adapter->setAuthProcessWrapper(&tars::processAuth);
|
||||
adapter->setAuthProcessWrapper(std::bind(tars::processAuth, std::placeholders::_1, std::placeholders::_2, _servantHelper->getAdapterServant(name)));
|
||||
//注意这里必须用weak, 否则adapter最终释放不了!
|
||||
weak_ptr<TC_EpollServer::BindAdapter> a = adapter;
|
||||
adapter->setAkSkCallback(accKey, secretKey, std::bind(&tars::serverVerifyAuthCallback, std::placeholders::_1, std::placeholders::_2, a, _servantHelper->getAdapterServant(name)));
|
||||
}
|
||||
|
||||
#if TARS_SSL
|
||||
|
@ -1328,8 +1338,6 @@ void Application::setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const stri
|
|||
|
||||
void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
|
||||
{
|
||||
// size_t iBackPacketBuffLimit = TC_Common::strto<size_t>(toDefault(_conf.get("/tars/application/server<BackPacketBuffLimit>", "0"), "0"));
|
||||
|
||||
string sPrefix = ServerConfig::Application + "." + ServerConfig::ServerName + ".";
|
||||
|
||||
vector<string> adapterName;
|
||||
|
@ -1346,11 +1354,6 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
|
|||
|
||||
_servantHelper->setAdapterServant(adapterName[i], servant);
|
||||
|
||||
TC_EpollServer::BindAdapterPtr bindAdapter = new TC_EpollServer::BindAdapter(_epollServer.get());
|
||||
|
||||
//init auth & ssl
|
||||
setAdapter(bindAdapter, adapterName[i]);
|
||||
|
||||
string sLastPath = "/tars/application/server/" + adapterName[i];
|
||||
TC_Endpoint ep;
|
||||
ep.parse(_conf[sLastPath + "<endpoint>"]);
|
||||
|
@ -1359,9 +1362,10 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
|
|||
ep.setHost(ServerConfig::LocalIp);
|
||||
}
|
||||
|
||||
bindAdapter->setName(adapterName[i]);
|
||||
TC_EpollServer::BindAdapterPtr bindAdapter = _epollServer->createBindAdapter<ServantHandle>(adapterName[i], _conf[sLastPath + "<endpoint>"], TC_Common::strto<int>(_conf.get(sLastPath + "<threads>", "1")), this);
|
||||
|
||||
bindAdapter->setEndpoint(_conf[sLastPath + "<endpoint>"]);
|
||||
//init auth & ssl
|
||||
setAdapter(bindAdapter, adapterName[i]);
|
||||
|
||||
bindAdapter->setMaxConns(TC_Common::strto<int>(_conf.get(sLastPath + "<maxconns>", "128")));
|
||||
|
||||
|
@ -1378,6 +1382,7 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
|
|||
bindAdapter->setProtocolName(_conf.get(sLastPath + "<protocol>", "tars"));
|
||||
|
||||
bindAdapter->setBackPacketBuffLimit(ServerConfig::BackPacketLimit);
|
||||
|
||||
bindAdapter->setBackPacketBuffMin(ServerConfig::BackPacketMin);
|
||||
|
||||
if (bindAdapter->isTarsProtocol())
|
||||
|
@ -1389,11 +1394,10 @@ void Application::bindAdapter(vector<TC_EpollServer::BindAdapterPtr>& adapters)
|
|||
#if TARS_SSL
|
||||
if (bindAdapter->getEndpoint().isSSL() && (!(bindAdapter->getSSLCtx())))
|
||||
{
|
||||
cout << "load server ssl error, no cert config!" << bindAdapter->getEndpoint().toString() << endl;
|
||||
__out__.error() << "load server ssl error, no cert config!" << bindAdapter->getEndpoint().toString() << endl;
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
bindAdapter->setHandle<ServantHandle>(TC_Common::strto<int>(_conf.get(sLastPath + "<threads>", "1")), this);
|
||||
|
||||
if(ServerConfig::ManualListen) {
|
||||
//手工监听
|
||||
|
@ -1429,11 +1433,9 @@ void Application::checkServantNameValid(const string& servant, const string& sPr
|
|||
|
||||
os << "Servant '" << servant << "' error: must be start with '" << sPrefix << "'";
|
||||
|
||||
RemoteNotify::getInstance()->report("exit:" + os.str());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); //稍微休息一下, 让当前处理包能够回复
|
||||
cout << os.str() << endl;
|
||||
|
||||
NOTIFY_AND_WAIT("exit: " + string(os.str()));
|
||||
|
||||
__out__.error() << os.str() << endl;
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "servant/Communicator.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/AdapterProxy.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
@ -30,29 +31,29 @@ AsyncProcThread::AsyncProcThread(size_t iQueueCap, bool merge)
|
|||
if(!_merge)
|
||||
{
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AsyncProcThread::~AsyncProcThread()
|
||||
{
|
||||
terminate();
|
||||
|
||||
if(_msgQueue)
|
||||
{
|
||||
delete _msgQueue;
|
||||
_msgQueue = NULL;
|
||||
}
|
||||
if(_msgQueue)
|
||||
{
|
||||
delete _msgQueue;
|
||||
_msgQueue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncProcThread::terminate()
|
||||
{
|
||||
if(!_merge) {
|
||||
TC_ThreadLock::Lock lock(*this);
|
||||
Lock lock(*this);
|
||||
|
||||
_terminate = true;
|
||||
_terminate = true;
|
||||
|
||||
notifyAll();
|
||||
}
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncProcThread::push_back(ReqMessage * msg)
|
||||
|
@ -77,25 +78,33 @@ void AsyncProcThread::push_back(ReqMessage * msg)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncProcThread::run()
|
||||
{
|
||||
while (!_terminate)
|
||||
{
|
||||
ReqMessage * msg;
|
||||
|
||||
//异步请求回来的响应包处理
|
||||
if (_msgQueue->pop_front(msg))
|
||||
{
|
||||
callback(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_ThreadLock::Lock lock(*this);
|
||||
timedWait(1000);
|
||||
TC_ThreadLock::Lock lock(*this);
|
||||
timedWait(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReqMessage * msg;
|
||||
while(_msgQueue->pop_front(msg))
|
||||
{
|
||||
delete msg;
|
||||
}
|
||||
|
||||
ServantProxyThreadData::g_sp.reset();
|
||||
CallbackThreadData::g_sp.reset();
|
||||
}
|
||||
|
||||
void AsyncProcThread::callback(ReqMessage * msg)
|
||||
{
|
||||
|
@ -103,17 +112,26 @@ void AsyncProcThread::callback(ReqMessage * msg)
|
|||
|
||||
//从回调对象把线程私有数据传递到回调线程中
|
||||
ServantProxyThreadData * pServantProxyThreadData = ServantProxyThreadData::getData();
|
||||
assert(pServantProxyThreadData != NULL);
|
||||
// assert(pServantProxyThreadData != NULL);
|
||||
|
||||
//把染色的消息设置在线程私有数据里面
|
||||
pServantProxyThreadData->_dyeing = msg->bDyeing;
|
||||
pServantProxyThreadData->_dyeingKey = msg->sDyeingKey;
|
||||
|
||||
pServantProxyThreadData->_cookie = msg->cookie;
|
||||
pServantProxyThreadData->_data._dyeing = msg->data._dyeing;
|
||||
pServantProxyThreadData->_data._dyeingKey = msg->data._dyeingKey;
|
||||
pServantProxyThreadData->_data._cookie = msg->data._cookie;
|
||||
//=======
|
||||
// pServantProxyThreadData->_dyeing = msg->bDyeing;
|
||||
// pServantProxyThreadData->_dyeingKey = msg->sDyeingKey;
|
||||
|
||||
pServantProxyThreadData->_traceCall = msg->bTraceCall;
|
||||
pServantProxyThreadData->initTrace(msg->sTraceKey);
|
||||
|
||||
// pServantProxyThreadData->_cookie = msg->cookie;
|
||||
//>>>>>>> origin/delay
|
||||
|
||||
if(msg->adapter)
|
||||
{
|
||||
pServantProxyThreadData->_szHost = msg->adapter->endpoint().desc();
|
||||
pServantProxyThreadData->_data._szHost = msg->adapter->endpoint().desc();
|
||||
}
|
||||
|
||||
try
|
||||
|
|
|
@ -22,116 +22,13 @@
|
|||
#include "servant/AuthLogic.h"
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include "tup/tup.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
bool processAuth(TC_EpollServer::Connection *conn, const shared_ptr<TC_EpollServer::RecvContext> &data, const string &objName)
|
||||
{
|
||||
conn->tryInitAuthState(AUTH_INIT);
|
||||
|
||||
if (conn->_authState == AUTH_SUCC)
|
||||
return false; // data to be processed
|
||||
|
||||
TC_EpollServer::BindAdapterPtr adapter = data->adapter();
|
||||
|
||||
int type = adapter->getEndpoint().getAuthType();
|
||||
if (type == AUTH_TYPENONE)
|
||||
{
|
||||
adapter->getEpollServer()->info("processAuth no need auth func, auth succ");
|
||||
conn->_authState = AUTH_SUCC;
|
||||
return false;
|
||||
}
|
||||
|
||||
// got auth request
|
||||
RequestPacket request;
|
||||
|
||||
if (adapter->isTarsProtocol())
|
||||
{
|
||||
TarsInputStream<BufferReader> is;
|
||||
|
||||
is.setBuffer(data->buffer().data(), data->buffer().size());
|
||||
|
||||
try
|
||||
{
|
||||
request.readFrom(is);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
adapter->getEpollServer()->error("processAuth tars protocol decode error, close connection.");
|
||||
|
||||
conn->setClose();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request.sBuffer = data->buffer();
|
||||
}
|
||||
|
||||
int currentState = conn->_authState;
|
||||
// int newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter->getName());
|
||||
int newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter, objName);
|
||||
std::string out = tars::etos((tars::AUTH_STATE)newstate);
|
||||
|
||||
if (newstate < 0)
|
||||
{
|
||||
// 验证错误,断开连接
|
||||
adapter->getEpollServer()->error("authProcess failed with new state [" + out + "]");
|
||||
conn->setClose();
|
||||
return true;
|
||||
}
|
||||
|
||||
adapter->getEpollServer()->info(TC_Common::tostr(conn->getId()) + "'s auth response[" + out + "], change state from " +
|
||||
tars::etos((tars::AUTH_STATE)currentState) + " to " + out);
|
||||
conn->_authState = newstate;
|
||||
|
||||
shared_ptr<TC_EpollServer::SendContext> sData = data->createSendContext();
|
||||
|
||||
if (adapter->isTarsProtocol())
|
||||
{
|
||||
TarsOutputStream<BufferWriterVector> os;
|
||||
|
||||
ResponsePacket response;
|
||||
response.iVersion = TARSVERSION;
|
||||
response.iRequestId = request.iRequestId;
|
||||
response.iMessageType = request.iMessageType;
|
||||
response.cPacketType = request.cPacketType;
|
||||
response.iRet = 0;
|
||||
response.sBuffer.assign(out.begin(), out.end());
|
||||
|
||||
int iHeaderLen = 0;
|
||||
|
||||
// 先预留4个字节长度
|
||||
os.writeBuf((const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
response.writeTo(os);
|
||||
|
||||
vector<char> buff;
|
||||
|
||||
buff.swap(os.getByteBuffer());
|
||||
|
||||
assert(buff.size() >= 4);
|
||||
|
||||
iHeaderLen = htonl((int)(buff.size()));
|
||||
|
||||
memcpy((void*)buff.data(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
sData->buffer()->swap(buff);
|
||||
}
|
||||
else
|
||||
{
|
||||
sData->buffer()->assign(out.c_str(), out.size());
|
||||
}
|
||||
|
||||
adapter->getEpollServer()->send(sData);
|
||||
|
||||
return true; // processed
|
||||
}
|
||||
|
||||
|
||||
int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
|
||||
AUTH_STATE processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
|
||||
{
|
||||
// 明文:objName, accessKey, time, hashMethod
|
||||
// 密文:use TmpKey to enc secret1;
|
||||
|
@ -198,8 +95,7 @@ int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
|
|||
|
||||
// 只需要传入 expect 的objname;
|
||||
// 内部根据obj查找access账号集
|
||||
//int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj)
|
||||
int defaultProcessAuthReq(const char* request, size_t len, const TC_EpollServer::BindAdapterPtr &adapter, const string &objName)
|
||||
AUTH_STATE defaultProcessAuthReq(const char* request, size_t len, TC_EpollServer::BindAdapterPtr& adapter, const string &expectObj)
|
||||
{
|
||||
if (len <= 20)
|
||||
return AUTH_PROTO_ERR;
|
||||
|
@ -218,53 +114,138 @@ int defaultProcessAuthReq(const char* request, size_t len, const TC_EpollServer:
|
|||
// if (!bap)
|
||||
// return AUTH_WRONG_OBJ;
|
||||
|
||||
BasicAuthInfo info;
|
||||
// string expectServantName = ServantHelperManager::getInstance()->getAdapterServant(expectObj);
|
||||
info.sObjName = objName;
|
||||
info.sAccessKey = pkg.sAccessKey;
|
||||
info.sHashSecretKey2 = adapter->getSk(info.sAccessKey);
|
||||
if (info.sHashSecretKey2.empty())
|
||||
return AUTH_WRONG_AK;
|
||||
BasicAuthInfo info;
|
||||
string expectServantName = expectObj;
|
||||
info.sObjName = expectServantName;
|
||||
info.sAccessKey = pkg.sAccessKey;
|
||||
info.sHashSecretKey2 = adapter->getSk(info.sAccessKey);
|
||||
if (info.sHashSecretKey2.empty())
|
||||
return AUTH_WRONG_AK;
|
||||
|
||||
return processAuthReqHelper(pkg, info);
|
||||
return processAuthReqHelper(pkg, info);
|
||||
}
|
||||
|
||||
//int defaultProcessAuthReq(const string& request, const string& expectObj)
|
||||
//{
|
||||
// return defaultProcessAuthReq(request.data(), request.size(), expectObj);
|
||||
//}
|
||||
AUTH_STATE defaultProcessAuthReq(const string& request, TC_EpollServer::BindAdapterPtr& adapter, const string& expectObj)
|
||||
{
|
||||
return defaultProcessAuthReq(request.data(), request.size(), adapter, expectObj);
|
||||
}
|
||||
|
||||
string defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMethod*/ )
|
||||
vector<char> defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMethod*/ )
|
||||
{
|
||||
// 明文:objName, accessKey, time, hashMethod
|
||||
// 密文:use TmpKey to enc secret1;
|
||||
TarsOutputStream<BufferWriterString> os;
|
||||
TarsOutputStream<BufferWriterVector> os;
|
||||
BasicAuthPackage pkg;
|
||||
pkg.sObjName = info.sObjName;
|
||||
pkg.sAccessKey = info.sAccessKey;
|
||||
pkg.iTime = TNOW;
|
||||
|
||||
string secret1 = TC_SHA::sha1str(info.sSecretKey.data(), info.sSecretKey.size());
|
||||
string secret2 = TC_SHA::sha1str(secret1.data(), secret1.size());
|
||||
string secret1 = TC_SHA::sha1str(info.sSecretKey.data(), info.sSecretKey.size());
|
||||
string secret2 = TC_SHA::sha1str(secret1.data(), secret1.size());
|
||||
|
||||
// create tmpKey
|
||||
// create tmpKey
|
||||
string tmpKey;
|
||||
{
|
||||
string tmp = secret2;
|
||||
const char* pt = (const char* )&pkg.iTime;
|
||||
for (size_t i = 0; i < sizeof pkg.iTime; ++ i)
|
||||
{
|
||||
tmp[i] |= pt[i];
|
||||
}
|
||||
// 只用了前面24字节
|
||||
tmpKey = TC_MD5::md5str(tmp);
|
||||
}
|
||||
{
|
||||
string tmp = secret2;
|
||||
const char* pt = (const char* )&pkg.iTime;
|
||||
for (size_t i = 0; i < sizeof pkg.iTime; ++ i)
|
||||
{
|
||||
tmp[i] |= pt[i];
|
||||
}
|
||||
// 保证key是16字节
|
||||
tmpKey = TC_MD5::md5str(tmp);
|
||||
}
|
||||
|
||||
pkg.sSignature = TC_Des::encrypt3(tmpKey.data(), secret1.data(), secret1.size());
|
||||
|
||||
pkg.writeTo(os);
|
||||
pkg.writeTo(os);
|
||||
|
||||
return os.getByteBuffer();
|
||||
return os.getByteBuffer();
|
||||
}
|
||||
|
||||
pair<TC_NetWorkBuffer::PACKET_TYPE, shared_ptr<TC_NetWorkBuffer::Buffer>> serverVerifyAuthCallback(TC_NetWorkBuffer &buff, TC_Transceiver* trans, weak_ptr<TC_EpollServer::BindAdapter> adapterPtr, const string &expectObj)
|
||||
{
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> data = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
|
||||
auto adapter = adapterPtr.lock();
|
||||
if(!adapter)
|
||||
{
|
||||
data->addBuffer("adapter release");
|
||||
return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
|
||||
}
|
||||
|
||||
// got auth request
|
||||
RequestPacket request;
|
||||
|
||||
if (adapter->isTarsProtocol())
|
||||
{
|
||||
TarsInputStream<BufferReader> is;
|
||||
|
||||
is.setBuffer(buff.mergeBuffers(), buff.getBufferLength());
|
||||
|
||||
try
|
||||
{
|
||||
request.readFrom(is);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
adapter->getEpollServer()->error("serverVerifyCallback protocol decode error, close connection.");
|
||||
return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request.sBuffer = buff.getBuffers();
|
||||
}
|
||||
|
||||
AUTH_STATE newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter, expectObj);
|
||||
std::string out = tars::etos((tars::AUTH_STATE)newstate);
|
||||
|
||||
if (newstate != AUTH_SUCC)
|
||||
{
|
||||
// 验证错误,断开连接
|
||||
adapter->getEpollServer()->error("authProcess failed with new state [" + out + "]");
|
||||
return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
|
||||
}
|
||||
|
||||
buff.clearBuffers();
|
||||
|
||||
string host;
|
||||
uint16_t port;
|
||||
TC_Socket::parseAddr(trans->getClientAddr(), host, port);
|
||||
|
||||
adapter->getEpollServer()->info(host+ ":" + TC_Common::tostr(port) + ", auth response succ: [" + out + "]");
|
||||
|
||||
if (adapter->isTarsProtocol())
|
||||
{
|
||||
TarsOutputStream<BufferWriter> os;
|
||||
|
||||
ResponsePacket response;
|
||||
response.iVersion = TARSVERSION;
|
||||
response.iRequestId = request.iRequestId;
|
||||
response.iMessageType = request.iMessageType;
|
||||
response.cPacketType = request.cPacketType;
|
||||
response.iRet = 0;
|
||||
response.sBuffer.assign(out.begin(), out.end());
|
||||
|
||||
tars::Int32 iHeaderLen = 0;
|
||||
|
||||
os.writeBuf((const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
response.writeTo(os);
|
||||
|
||||
iHeaderLen = htonl((int)(os.getLength()));
|
||||
|
||||
memcpy((void*)os.getBuffer(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
data = ProxyProtocol::toBuffer(os);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->addBuffer(out.c_str(), out.size());
|
||||
}
|
||||
|
||||
return std::make_pair(TC_NetWorkBuffer::PACKET_FULL, data);
|
||||
}
|
||||
|
||||
} // end namespace tars
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
if(TARS_OPENTRACKING)
|
||||
include_directories(${PROJECT_SOURCE_DIR} ${OPENTRACKING_INC})
|
||||
else()
|
||||
# if(TARS_OPENTRACKING)
|
||||
# include_directories(${PROJECT_SOURCE_DIR} ${OPENTRACKING_INC})
|
||||
# else()
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
endif()
|
||||
# endif()
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_epoller.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/Application.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "util/tc_file.h"
|
||||
#include "servant/ObjectProxy.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
@ -42,39 +44,43 @@ string ClientConfig::TarsVersion = string(TARS_VERSION);
|
|||
Communicator::Communicator()
|
||||
: _initialized(false)
|
||||
, _terminating(false)
|
||||
, _clientThreadNum(1)
|
||||
|
||||
, _statReport(NULL)
|
||||
, _timeoutLogFlag(true)
|
||||
, _minTimeout(100)
|
||||
#ifdef TARS_OPENTRACKING
|
||||
, _traceManager(NULL)
|
||||
#endif
|
||||
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// , _traceManager(NULL)
|
||||
// #endif
|
||||
{
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||
#endif
|
||||
memset(_communicatorEpoll,0,sizeof(_communicatorEpoll));
|
||||
|
||||
}
|
||||
|
||||
Communicator::Communicator(TC_Config& conf, const string& domain/* = CONFIG_ROOT_PATH*/)
|
||||
: _initialized(false)
|
||||
, _terminating(false)
|
||||
, _timeoutLogFlag(true)
|
||||
#ifdef TARS_OPENTRACKING
|
||||
, _traceManager(NULL)
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// , _traceManager(NULL)
|
||||
// #endif
|
||||
{
|
||||
setProperty(conf, domain);
|
||||
}
|
||||
|
||||
Communicator::~Communicator()
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
ServantProxyThreadData::deconstructor(this);
|
||||
|
||||
terminate();
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool Communicator::isTerminating()
|
||||
|
@ -84,61 +90,65 @@ bool Communicator::isTerminating()
|
|||
|
||||
map<string, string> Communicator::getServantProperty(const string &sObj)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
auto it = _objInfo.find(sObj);
|
||||
if (it != _objInfo.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
auto it = _objInfo.find(sObj);
|
||||
if(it != _objInfo.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return map<string, string>();
|
||||
return map<string, string>();
|
||||
}
|
||||
|
||||
void Communicator::setServantProperty(const string &sObj, const string &name, const string &value)
|
||||
void Communicator::setServantProperty(const string &sObj, const string& name, const string& value)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
_objInfo[sObj][name] = value;
|
||||
_objInfo[sObj][name] = value;
|
||||
}
|
||||
|
||||
string Communicator::getServantProperty(const string &sObj, const string &name)
|
||||
string Communicator::getServantProperty(const string &sObj, const string& name)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
auto it = _objInfo.find(sObj);
|
||||
if (it != _objInfo.end())
|
||||
{
|
||||
auto vit = it->second.find(name);
|
||||
auto it = _objInfo.find(sObj);
|
||||
if(it != _objInfo.end())
|
||||
{
|
||||
auto vit = it->second.find(name);
|
||||
|
||||
if (vit != it->second.end())
|
||||
{
|
||||
return vit->second;
|
||||
}
|
||||
}
|
||||
if(vit != it->second.end())
|
||||
{
|
||||
return vit->second;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
shared_ptr<TC_OpenSSL> Communicator::newClientSSL(const string & objName)
|
||||
{
|
||||
#if TARS_SSL
|
||||
shared_ptr<TC_OpenSSL> Communicator::newClientSSL(const string &objName)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
auto it = _objCtx.find(objName);
|
||||
if (it != _objCtx.end())
|
||||
{
|
||||
return TC_OpenSSL::newSSL(it->second);
|
||||
}
|
||||
auto it = _objCtx.find(objName);
|
||||
if(it != _objCtx.end())
|
||||
{
|
||||
return TC_OpenSSL::newSSL(it->second);
|
||||
}
|
||||
|
||||
if(!_ctx) {
|
||||
_ctx = TC_OpenSSL::newCtx("", "", "", false, "");
|
||||
}
|
||||
|
||||
return TC_OpenSSL::newSSL(_ctx);
|
||||
return TC_OpenSSL::newSSL(_ctx);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Communicator::setProperty(TC_Config& conf, const string& domain/* = CONFIG_ROOT_PATH*/)
|
||||
{
|
||||
|
@ -153,48 +163,70 @@ void Communicator::setProperty(TC_Config& conf, const string& domain/* = CONFIG_
|
|||
_properties["setdivision"] = conf.get("/tars/application<setdivision>", "NULL");
|
||||
}
|
||||
|
||||
vector<string> auths;
|
||||
vector<string> auths;
|
||||
|
||||
if (conf.getDomainVector("/tars/application/client", auths))
|
||||
if (conf.getDomainVector(CONFIG_ROOT_PATH, auths))
|
||||
{
|
||||
for(size_t i = 0; i < auths.size(); i++)
|
||||
{
|
||||
map<string, string> &data = _objInfo[auths[i]];
|
||||
data["accesskey"] = conf.get("/tars/application/client/" + auths[i] + "<accesskey>");
|
||||
data["secretkey"] = conf.get("/tars/application/client/" + auths[i] + "<secretkey>");
|
||||
data["ca"] = conf.get("/tars/application/client/" + auths[i] + "<ca>");
|
||||
data["cert"] = conf.get("/tars/application/client/" + auths[i] + "<cert>");
|
||||
data["key"] = conf.get("/tars/application/client/" + auths[i] + "<key>");
|
||||
data["ciphers"] = conf.get("/tars/application/client/" + auths[i] + "<ciphers>");
|
||||
|
||||
data["accesskey"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<accesskey>");
|
||||
data["secretkey"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<secretkey>");
|
||||
data["ca"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<ca>");
|
||||
data["cert"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<cert>");
|
||||
data["key"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<key>");
|
||||
data["ciphers"] = conf.get(CONFIG_ROOT_PATH + "/" + auths[i] + "<ciphers>");
|
||||
#if TARS_SSL
|
||||
|
||||
if (!data["ca"].empty())
|
||||
{
|
||||
shared_ptr<TC_OpenSSL::CTX> ctx = TC_OpenSSL::newCtx(data["ca"], data["cert"], data["key"], false, data["ciphers"]);
|
||||
if (!ctx)
|
||||
{
|
||||
TLOGERROR("load obj:" << auths[i] << ", ssl error, ca:" << data["ca"] << endl);
|
||||
exit(-1);
|
||||
}
|
||||
if(!data["ca"].empty())
|
||||
{
|
||||
shared_ptr<TC_OpenSSL::CTX> ctx = TC_OpenSSL::newCtx( data["ca"], data["cert"], data["key"], false, data["ciphers"]);
|
||||
if(!ctx)
|
||||
{
|
||||
TLOGERROR("[load obj:" << auths[i] << ", ssl error, ca:" << data["ca"] << endl);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
_objCtx[auths[i]] = ctx;
|
||||
}
|
||||
_objCtx[auths[i]] = ctx;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initClientConfig();
|
||||
}
|
||||
|
||||
void Communicator::notifyCommunicatorEpollStart()
|
||||
{
|
||||
++_communicatorEpollStartNum;
|
||||
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
|
||||
_cond.notify_one();
|
||||
}
|
||||
|
||||
void Communicator::initialize()
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
if (_initialized) return;
|
||||
//两次保护
|
||||
if (_initialized)
|
||||
return;
|
||||
|
||||
_initialized = true;
|
||||
|
||||
_sigId = TC_Port::registerCtrlC([&]{
|
||||
|
||||
TC_Common::msleep(50);
|
||||
this->terminate();
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
ExitProcess(0);
|
||||
#else
|
||||
exit(0);
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
ClientConfig::TarsVersion = TARS_VERSION;
|
||||
|
||||
ClientConfig::SetOpen = TC_Common::lower(getProperty("enableset", "n")) == "y" ? true : false;
|
||||
|
@ -207,12 +239,14 @@ void Communicator::initialize()
|
|||
|
||||
string sWildCard = "*";
|
||||
|
||||
if (vtSetDivisions.size() != 3 || vtSetDivisions[0] == sWildCard || vtSetDivisions[1] == sWildCard)
|
||||
if (vtSetDivisions.size() != 3
|
||||
|| vtSetDivisions[0] == sWildCard
|
||||
|| vtSetDivisions[1] == sWildCard)
|
||||
{
|
||||
//set分组名不对时默认没有打开set分组
|
||||
ClientConfig::SetOpen = false;
|
||||
setProperty("enableset","n");
|
||||
TLOGERROR( "[set division name error:" << ClientConfig::SetDivision << ", client failed to open set]" << endl);
|
||||
setProperty("enableset", "n");
|
||||
TLOGERROR("[set division name error:" << ClientConfig::SetDivision << ", client failed to open set]" << endl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,7 +272,7 @@ void Communicator::initialize()
|
|||
{
|
||||
exe = TC_File::extractFileName(TC_File::getExePath());
|
||||
}
|
||||
catch (TC_File_Exception &ex)
|
||||
catch (TC_File_Exception& ex)
|
||||
{
|
||||
//取失败则使用ip代替进程名
|
||||
exe = ClientConfig::LocalIp;
|
||||
|
@ -248,10 +282,10 @@ void Communicator::initialize()
|
|||
|
||||
#if TARS_SSL
|
||||
|
||||
string ca = getProperty("ca");
|
||||
string cert = getProperty("cert");
|
||||
string key = getProperty("key");
|
||||
string ciphers = getProperty("ciphers");
|
||||
string ca = getProperty("ca");
|
||||
string cert = getProperty("cert");
|
||||
string key = getProperty("key");
|
||||
string ciphers = getProperty("ciphers");
|
||||
|
||||
if(!ca.empty()) {
|
||||
_ctx = TC_OpenSSL::newCtx(ca, cert, key, false, ciphers);
|
||||
|
@ -267,56 +301,64 @@ void Communicator::initialize()
|
|||
_servantProxyFactory = new ServantProxyFactory(this);
|
||||
|
||||
//网络线程
|
||||
_clientThreadNum = TC_Common::strto<size_t>(getProperty("netthread", "1"));
|
||||
size_t clientThreadNum = TC_Common::strto<size_t>(getProperty("netthread", "1"));
|
||||
|
||||
if (0 == _clientThreadNum)
|
||||
if (0 == clientThreadNum)
|
||||
{
|
||||
_clientThreadNum = 1;
|
||||
clientThreadNum = 1;
|
||||
}
|
||||
else if (MAX_CLIENT_THREAD_NUM < _clientThreadNum)
|
||||
else if(MAX_CLIENT_THREAD_NUM < clientThreadNum)
|
||||
{
|
||||
_clientThreadNum = MAX_CLIENT_THREAD_NUM;
|
||||
clientThreadNum = MAX_CLIENT_THREAD_NUM;
|
||||
}
|
||||
|
||||
//异步线程数
|
||||
_asyncThreadNum = TC_Common::strto<size_t>(getProperty("asyncthread", "3"));
|
||||
|
||||
if (_asyncThreadNum == 0)
|
||||
if(_asyncThreadNum == 0)
|
||||
{
|
||||
_asyncThreadNum = 3;
|
||||
}
|
||||
|
||||
if (_asyncThreadNum > MAX_CLIENT_ASYNCTHREAD_NUM)
|
||||
if(_asyncThreadNum > MAX_CLIENT_ASYNCTHREAD_NUM)
|
||||
{
|
||||
_asyncThreadNum = MAX_CLIENT_ASYNCTHREAD_NUM;
|
||||
}
|
||||
|
||||
bool merge = TC_Common::strto<bool>(getProperty("mergenetasync", "0"));
|
||||
bool merge = TC_Common::strto<bool>(getProperty("mergenetasync", "0"));
|
||||
|
||||
//异步队列的大小
|
||||
size_t iAsyncQueueCap = TC_Common::strto<size_t>(getProperty("asyncqueuecap", "100000"));
|
||||
if (iAsyncQueueCap < 10000)
|
||||
if(iAsyncQueueCap < 10000)
|
||||
{
|
||||
iAsyncQueueCap = 10000;
|
||||
}
|
||||
|
||||
//第一个通信器才去启动回调线程
|
||||
for (size_t i = 0; i < _asyncThreadNum; ++i) {
|
||||
_asyncThread.push_back(new AsyncProcThread(iAsyncQueueCap, merge));
|
||||
}
|
||||
//第一个通信器才去启动回调线程
|
||||
for (size_t i = 0; i < _asyncThreadNum; ++i) {
|
||||
_asyncThread.push_back(new AsyncProcThread(iAsyncQueueCap, merge));
|
||||
}
|
||||
|
||||
//stat总是有对象, 保证getStat返回的对象总是有效
|
||||
_statReport = new StatReport(_clientThreadNum);
|
||||
_statReport = new StatReport(this);
|
||||
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
for (size_t i = 0; i < clientThreadNum; ++i)
|
||||
{
|
||||
_communicatorEpoll[i] = new CommunicatorEpoll(this, i);
|
||||
_communicatorEpoll[i]->start();
|
||||
_communicatorEpoll.push_back(std::make_shared<CommunicatorEpoll>(this, -1, i == 0));
|
||||
|
||||
//以协程模式启动
|
||||
_communicatorEpoll.back()->setThreadName("communicator-epoll-" + TC_Common::tostr(i));
|
||||
_communicatorEpoll.back()->startCoroutine(3, 128*1024, false);
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cond.wait(lock, [&]{ return _communicatorEpollStartNum == clientThreadNum; });
|
||||
}
|
||||
|
||||
//异步队列数目上报
|
||||
_reportAsyncQueue = getStatReport()->createPropertyReport(ClientConfig::ModuleName + ".asyncqueue", PropertyReport::avg());
|
||||
|
||||
_reportAsyncQueue= getStatReport()->createPropertyReport(ClientConfig::ModuleName + ".asyncqueue", PropertyReport::avg());
|
||||
|
||||
//初始化统计上报接口
|
||||
string statObj = getProperty("stat", "");
|
||||
|
||||
|
@ -335,7 +377,7 @@ void Communicator::initialize()
|
|||
_timeoutLogFlag = TC_Common::strto<bool>(getProperty("timeout-log-flag", "1"));
|
||||
|
||||
_minTimeout = TC_Common::strto<int64_t>(getProperty("min-timeout", "100"));
|
||||
if (_minTimeout < 1)
|
||||
if(_minTimeout < 1)
|
||||
_minTimeout = 1;
|
||||
|
||||
StatFPrx statPrx = NULL;
|
||||
|
@ -351,8 +393,8 @@ void Communicator::initialize()
|
|||
propertyPrx = stringToProxy<PropertyFPrx>(propertyObj);
|
||||
}
|
||||
|
||||
string sSetDivision = ClientConfig::SetOpen?ClientConfig::SetDivision:"";
|
||||
_statReport->setReportInfo(statPrx, propertyPrx, ClientConfig::ModuleName, ClientConfig::LocalIp, sSetDivision, iReportInterval, 0, 0, iMaxReportSize, iReportTimeout);
|
||||
string sSetDivision = ClientConfig::SetOpen ? ClientConfig::SetDivision : "";
|
||||
_statReport->setReportInfo(statPrx, propertyPrx, ClientConfig::ModuleName, ClientConfig::LocalIp, sSetDivision, iReportInterval, 0, 0, iMaxReportSize, iReportTimeout);
|
||||
|
||||
#if TARS_OPENTRACKING
|
||||
string collector_host = getProperty("collector_host", "");
|
||||
|
@ -375,21 +417,21 @@ void Communicator::initialize()
|
|||
}
|
||||
|
||||
|
||||
void Communicator::setProperty(const map<string, string> &properties)
|
||||
void Communicator::setProperty(const map<string, string>& properties)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
_properties = properties;
|
||||
}
|
||||
|
||||
void Communicator::setProperty(const string &name, const string &value)
|
||||
void Communicator::setProperty(const string& name, const string& value)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
_properties[name] = value;
|
||||
}
|
||||
|
||||
string Communicator::getProperty(const string &name, const string &dft /* = ""*/)
|
||||
string Communicator::getProperty(const string& name, const string& dft/* = ""*/)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
|
@ -402,29 +444,86 @@ string Communicator::getProperty(const string &name, const string &dft /* = ""*/
|
|||
return dft;
|
||||
}
|
||||
|
||||
void Communicator::reloadLocator()
|
||||
vector<shared_ptr<CommunicatorEpoll>> Communicator::getAllCommunicatorEpoll()
|
||||
{
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
{
|
||||
_communicatorEpoll[i]->getObjectProxyFactory()->loadObjectLocator();
|
||||
}
|
||||
vector<shared_ptr<CommunicatorEpoll>> communicatorEpolls = _communicatorEpoll;
|
||||
|
||||
forEachSchedCommunicatorEpoll([&](const shared_ptr<CommunicatorEpoll> &c){
|
||||
communicatorEpolls.push_back(c);
|
||||
});
|
||||
|
||||
return communicatorEpolls;
|
||||
}
|
||||
|
||||
int Communicator::reloadProperty(string &sResult)
|
||||
void Communicator::forEachSchedCommunicatorEpoll(std::function<void(const shared_ptr<CommunicatorEpoll> &)> func)
|
||||
{
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
TC_LockT<TC_SpinLock> lock(_schedMutex);
|
||||
for(auto it : _schedCommunicatorEpoll)
|
||||
{
|
||||
func(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<CommunicatorEpoll> Communicator::createSchedCommunicatorEpoll(size_t netThreadSeq, const shared_ptr<ReqInfoQueue> &reqInfoQueue)
|
||||
{
|
||||
shared_ptr<CommunicatorEpoll> communicatorEpoll = std::make_shared<CommunicatorEpoll>(this, netThreadSeq);
|
||||
|
||||
communicatorEpoll->initializeEpoller();
|
||||
|
||||
communicatorEpoll->initNotify(netThreadSeq, reqInfoQueue);
|
||||
|
||||
{
|
||||
TC_LockT<TC_SpinLock> lock(_schedMutex);
|
||||
|
||||
_schedCommunicatorEpoll.insert(std::make_pair(netThreadSeq, communicatorEpoll));
|
||||
}
|
||||
|
||||
return communicatorEpoll;
|
||||
}
|
||||
|
||||
void Communicator::eraseSchedCommunicatorEpoll(size_t netThreadSeq)
|
||||
{
|
||||
shared_ptr<CommunicatorEpoll> ce;
|
||||
{
|
||||
TC_LockT<TC_SpinLock> lock(_schedMutex);
|
||||
|
||||
ce = _schedCommunicatorEpoll[netThreadSeq];
|
||||
|
||||
_schedCommunicatorEpoll.erase(netThreadSeq);
|
||||
}
|
||||
|
||||
if(ce)
|
||||
{
|
||||
ce->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void Communicator::reloadLocator()
|
||||
{
|
||||
for (size_t i = 0; i < _communicatorEpoll.size(); ++i)
|
||||
{
|
||||
_communicatorEpoll[i]->getObjectProxyFactory()->loadObjectLocator();
|
||||
_communicatorEpoll[i]->_epoller->syncCallback(std::bind(&CommunicatorEpoll::loadObjectLocator, _communicatorEpoll[i].get()));
|
||||
|
||||
// _communicatorEpoll[i]->loadObjectLocator();
|
||||
}
|
||||
|
||||
forEachSchedCommunicatorEpoll([](const shared_ptr<CommunicatorEpoll> &c){
|
||||
c->_epoller->syncCallback(std::bind(&CommunicatorEpoll::loadObjectLocator, c.get()));
|
||||
// c->loadObjectLocator();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
int Communicator::reloadProperty(string & sResult)
|
||||
{
|
||||
// size_t num = getCommunicatorEpollNum();
|
||||
|
||||
reloadLocator();
|
||||
|
||||
int iReportInterval = TC_Common::strto<int>(getProperty("report-interval", "60000"));
|
||||
|
||||
int iReportTimeout = TC_Common::strto<int>(getProperty("report-timeout", "5000"));
|
||||
|
||||
// int iSampleRate = TC_Common::strto<int>(getProperty("sample-rate", "1000"));
|
||||
|
||||
// int iMaxSampleCount = TC_Common::strto<int>(getProperty("max-sample-count", "100"));
|
||||
|
||||
int iMaxReportSize = TC_Common::strto<int>(getProperty("max-report-size", "1400"));
|
||||
|
||||
string statObj = getProperty("stat", "");
|
||||
|
@ -449,23 +548,23 @@ int Communicator::reloadProperty(string &sResult)
|
|||
_statReport->setReportInfo(statPrx, propertyPrx, ClientConfig::ModuleName, ClientConfig::LocalIp, sSetDivision, iReportInterval, 0, 0, iMaxReportSize, iReportTimeout);
|
||||
|
||||
sResult = "locator=" + getProperty("locator", "") + "\r\n" +
|
||||
"stat=" + statObj + "\r\n" + "property=" + propertyObj + "\r\n" +
|
||||
"SetDivision=" + sSetDivision + "\r\n" +
|
||||
"report-interval=" + TC_Common::tostr(iReportInterval) + "\r\n" +
|
||||
"report-timeout=" + TC_Common::tostr(iReportTimeout) + "\r\n";
|
||||
// "sample-rate=" + TC_Common::tostr(iSampleRate) + "\r\n" +
|
||||
// "max-sample-count=" + TC_Common::tostr(iMaxSampleCount) + "\r\n";
|
||||
"stat=" + statObj + "\r\n" + "property=" + propertyObj + "\r\n" +
|
||||
"SetDivision=" + sSetDivision + "\r\n" +
|
||||
"report-interval=" + TC_Common::tostr(iReportInterval) + "\r\n" +
|
||||
"report-timeout=" + TC_Common::tostr(iReportTimeout) + "\r\n";
|
||||
// "sample-rate=" + TC_Common::tostr(iSampleRate) + "\r\n" +
|
||||
// "max-sample-count=" + TC_Common::tostr(iMaxSampleCount) + "\r\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector<TC_Endpoint> Communicator::getEndpoint(const string &objName)
|
||||
vector<TC_Endpoint> Communicator::getEndpoint(const string& objName)
|
||||
{
|
||||
ServantProxy * pServantProxy = getServantProxy(objName);
|
||||
return pServantProxy->getEndpoint();
|
||||
}
|
||||
|
||||
vector<TC_Endpoint> Communicator::getEndpoint4All(const string &objName)
|
||||
vector<TC_Endpoint> Communicator::getEndpoint4All(const string& objName)
|
||||
{
|
||||
ServantProxy *pServantProxy = getServantProxy(objName);
|
||||
return pServantProxy->getEndpoint4All();
|
||||
|
@ -474,161 +573,164 @@ vector<TC_Endpoint> Communicator::getEndpoint4All(const string &objName)
|
|||
string Communicator::getResourcesInfo()
|
||||
{
|
||||
ostringstream os;
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
|
||||
for (size_t i = 0; i < _communicatorEpoll.size(); ++i)
|
||||
{
|
||||
os << OUT_LINE << endl;
|
||||
os << _communicatorEpoll[i]->getResourcesInfo();
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void Communicator::notifyUpdateEndpoints(const ServantPrx &prx, const set<EndpointInfo> &active, const set<EndpointInfo> &inactive)
|
||||
{
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
{
|
||||
_communicatorEpoll[i]->notifyUpdateEndpoints(prx, active, inactive);
|
||||
_communicatorEpoll[i]->_epoller->syncCallback(std::bind(&CommunicatorEpoll::getResourcesInfo, _communicatorEpoll[i].get(), std::ref(os)));
|
||||
}
|
||||
|
||||
forEachSchedCommunicatorEpoll([&](const shared_ptr<CommunicatorEpoll> & c){
|
||||
os << OUT_LINE << endl;
|
||||
c->_epoller->syncCallback(std::bind(&CommunicatorEpoll::getResourcesInfo, c.get(), std::ref(os)));
|
||||
});
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void Communicator::terminate()
|
||||
{
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
if (_terminating)
|
||||
return;
|
||||
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
_terminating = true;
|
||||
|
||||
TC_Port::unregisterCtrlC(_sigId);
|
||||
|
||||
if (_initialized)
|
||||
{
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
//先要结束stat的, 这样后续结束可以把stat队列清空
|
||||
if (_statReport)
|
||||
{
|
||||
_statReport->terminate();
|
||||
|
||||
_statReport->getThreadControl().join();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _communicatorEpoll.size(); ++i)
|
||||
{
|
||||
if(_communicatorEpoll[i]) {
|
||||
_communicatorEpoll[i]->terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_statReport)
|
||||
forEachSchedCommunicatorEpoll([](const shared_ptr<CommunicatorEpoll> &c)
|
||||
{
|
||||
c->terminate();
|
||||
});
|
||||
|
||||
for(size_t i = 0;i < _asyncThreadNum; ++i)
|
||||
{
|
||||
_statReport->terminate();
|
||||
_asyncThread[i]->terminate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 释放当前线程数据
|
||||
// ServantProxyThreadData::reset();
|
||||
|
||||
//把锁释放掉, 再来等待线程停止, 避免死锁
|
||||
//把锁释放掉, 再来等待线程停止, 避免死锁
|
||||
//因为通信器线程运行过程中, 有可能加上上面那把锁
|
||||
if (_initialized)
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
|
||||
//停止掉异步线程
|
||||
for (size_t i = 0; i < _asyncThread.size(); ++i)
|
||||
{
|
||||
if (_asyncThread[i])
|
||||
{
|
||||
if (_asyncThread[i]->isAlive())
|
||||
if (_asyncThread[i]->joinable())
|
||||
{
|
||||
_asyncThread[i]->terminate();
|
||||
_asyncThread[i]->getThreadControl().join();
|
||||
_asyncThread[i]->join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//停止掉网络线程
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
for (size_t i = 0; i < _communicatorEpoll.size(); ++i)
|
||||
{
|
||||
if(_communicatorEpoll[i]) {
|
||||
_communicatorEpoll[i]->getThreadControl().join();
|
||||
}
|
||||
if(_communicatorEpoll[i]->joinable())
|
||||
{
|
||||
_communicatorEpoll[i]->join();
|
||||
}
|
||||
}
|
||||
|
||||
//都停止了, 再把异步线程析构掉(因为异步线程中会调用网络线程的数据)
|
||||
for (size_t i = 0; i < _asyncThread.size(); ++i)
|
||||
{
|
||||
if (_asyncThread[i])
|
||||
{
|
||||
delete _asyncThread[i];
|
||||
_asyncThread[i] = NULL;
|
||||
}
|
||||
delete _asyncThread[i];
|
||||
_asyncThread[i] = NULL;
|
||||
}
|
||||
_asyncThread.clear();
|
||||
|
||||
if (_statReport)
|
||||
{
|
||||
_statReport->getThreadControl().join();
|
||||
delete _statReport;
|
||||
_statReport = NULL;
|
||||
}
|
||||
|
||||
//delete网络线程
|
||||
for (size_t i = 0; i < _clientThreadNum; ++i)
|
||||
{
|
||||
if(_communicatorEpoll[i]) {
|
||||
delete _communicatorEpoll[i];
|
||||
_communicatorEpoll[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_servantProxyFactory)
|
||||
if(_statReport)
|
||||
{
|
||||
delete _statReport;
|
||||
_statReport = NULL;
|
||||
}
|
||||
if(_servantProxyFactory)
|
||||
{
|
||||
delete _servantProxyFactory;
|
||||
_servantProxyFactory = NULL;
|
||||
_servantProxyFactory = NULL;
|
||||
}
|
||||
|
||||
_communicatorEpoll.clear();
|
||||
_schedCommunicatorEpoll.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Communicator::pushAsyncThreadQueue(ReqMessage *msg)
|
||||
void Communicator::pushAsyncThreadQueue(ReqMessage * msg)
|
||||
{
|
||||
if (msg->pObjectProxy->getRootServantProxy()->_callback)
|
||||
{
|
||||
ReqMessagePtr msgPtr = msg;
|
||||
if(msg->pObjectProxy->getRootServantProxy()->_callback) {
|
||||
ReqMessagePtr msgPtr = msg;
|
||||
|
||||
msg->pObjectProxy->getRootServantProxy()->_callback(msgPtr);
|
||||
}
|
||||
msg->pObjectProxy->getRootServantProxy()->_callback(msgPtr);
|
||||
}
|
||||
else if (msg->pObjectProxy->getRootServantProxy()->_callbackHash)
|
||||
{
|
||||
//先不考虑每个线程队列数目不一致的情况
|
||||
_asyncThread[((uint32_t)msg->adapter->trans()->fd()) % _asyncThreadNum]->push_back(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
//先不考虑每个线程队列数目不一致的情况
|
||||
_asyncThread[(_asyncSeq++) % _asyncThreadNum]->push_back(msg);
|
||||
}
|
||||
else {
|
||||
//先不考虑每个线程队列数目不一致的情况
|
||||
_asyncThread[(_asyncSeq++) % _asyncThreadNum]->push_back(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Communicator::doStat()
|
||||
{
|
||||
//队列长度上报
|
||||
if (_reportAsyncQueue)
|
||||
{
|
||||
if (_reportAsyncQueue) {
|
||||
size_t n = 0;
|
||||
|
||||
for (size_t i = 0; i < _asyncThread.size(); ++i)
|
||||
{
|
||||
n = n + _asyncThread[i]->getSize();
|
||||
}
|
||||
_reportAsyncQueue->report((int)n);
|
||||
_reportAsyncQueue->report((int) n);
|
||||
}
|
||||
}
|
||||
|
||||
ServantProxy *Communicator::getServantProxy(const string &objectName, const string &setName)
|
||||
ServantProxy* Communicator::getServantProxy(const string& objectName, const string& setName)
|
||||
{
|
||||
Communicator::initialize();
|
||||
|
||||
return _servantProxyFactory->getServantProxy(objectName, setName);
|
||||
}
|
||||
|
||||
StatReport *Communicator::getStatReport()
|
||||
StatReport* Communicator::getStatReport()
|
||||
{
|
||||
Communicator::initialize();
|
||||
|
||||
return _statReport;
|
||||
}
|
||||
|
||||
ServantProxyFactory *Communicator::servantProxyFactory()
|
||||
ServantProxyFactory* Communicator::servantProxyFactory()
|
||||
{
|
||||
return _servantProxyFactory;
|
||||
}
|
||||
|
|
|
@ -18,453 +18,477 @@
|
|||
#include "servant/Communicator.h"
|
||||
#include "servant/Application.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/ObjectProxy.h"
|
||||
#include "servant/EndpointManager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
CommunicatorEpoll::CommunicatorEpoll(Communicator * pCommunicator,size_t netThreadSeq)
|
||||
#define MAX_STAT_QUEUE_SIZE 100000 //上报队列缓存大小
|
||||
|
||||
CommunicatorEpoll::CommunicatorEpoll(Communicator * pCommunicator,size_t netThreadSeq, bool isFirst)
|
||||
: _communicator(pCommunicator)
|
||||
, _terminate(false)
|
||||
, _nextTime(0)
|
||||
, _nextStatTime(0)
|
||||
, _objectProxyFactory(NULL)
|
||||
, _isFirst(isFirst)
|
||||
, _netThreadSeq(netThreadSeq)
|
||||
, _noSendQueueLimit(1000)
|
||||
, _timeoutCheckInterval(100)
|
||||
, _statQueue(MAX_STAT_QUEUE_SIZE)
|
||||
|
||||
{
|
||||
_ep.create(1024);
|
||||
|
||||
_terminateFDInfo.notify.init(&_ep);
|
||||
_terminateFDInfo.iType = FDInfo::ET_C_TERMINATE;
|
||||
_terminateFDInfo.notify.add((uint64_t)&_terminateFDInfo);
|
||||
|
||||
//ObjectProxyFactory 对象
|
||||
_objectProxyFactory = new ObjectProxyFactory(this);
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
|
||||
//节点队列未发送请求的大小限制
|
||||
_noSendQueueLimit = TC_Common::strto<size_t>(pCommunicator->getProperty("nosendqueuelimit", "100000"));
|
||||
_noSendQueueLimit = TC_Common::strto<size_t>(pCommunicator->getProperty("sendqueuelimit", pCommunicator->getProperty("nosendqueuelimit", "100000")));
|
||||
if(_noSendQueueLimit < 1000)
|
||||
{
|
||||
_noSendQueueLimit = 1000;
|
||||
}
|
||||
|
||||
//检查超时请求的时间间隔,单位:ms
|
||||
_timeoutCheckInterval = TC_Common::strto<int64_t>(pCommunicator->getProperty("timeoutcheckinterval", "100"));
|
||||
_timeoutCheckInterval = TC_Common::strto<int64_t>(pCommunicator->getProperty("timeoutcheckinterval", "1000"));
|
||||
if(_timeoutCheckInterval < 1)
|
||||
{
|
||||
_timeoutCheckInterval = 1;
|
||||
_timeoutCheckInterval = 5;
|
||||
}
|
||||
|
||||
for(size_t i = 0;i < MAX_CLIENT_NOTIFYEVENT_NUM;++i)
|
||||
{
|
||||
_notify[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CommunicatorEpoll::~CommunicatorEpoll()
|
||||
{
|
||||
for(size_t i = 0;i < MAX_CLIENT_NOTIFYEVENT_NUM;++i)
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::handleServantThreadQuit(uint16_t iSeq)
|
||||
{
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
//在网络线程中处理的!
|
||||
if(_notify[iSeq])
|
||||
{
|
||||
_notify[iSeq]->autoDestroy = true;
|
||||
|
||||
//通知网络线程, 网络线程好析构notify对象
|
||||
notify(iSeq);
|
||||
|
||||
_notify[iSeq] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::notifyServantThreadQuit(uint16_t iSeq)
|
||||
{
|
||||
|
||||
if(_scheduler)
|
||||
{
|
||||
//CommunicatorEpoll还没有退出!
|
||||
if (_threadId == this_thread::get_id())
|
||||
{
|
||||
//同一个线程里面结束, 直接释放相关资源即可
|
||||
CommunicatorEpoll::handleServantThreadQuit(iSeq);
|
||||
}
|
||||
else
|
||||
{
|
||||
//等待数据都发送出去, 避免业务线程退出以后, 还有数据没有发送出去, 这里处理不够优雅!
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
//再做一次判断
|
||||
if (_scheduler)
|
||||
{
|
||||
//通知网络线程去释放资源!
|
||||
_epoller->asyncCallback(std::bind(&CommunicatorEpoll::handleServantThreadQuit, this, iSeq));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::notifyTerminate()
|
||||
{
|
||||
if (_scheduler)
|
||||
{
|
||||
if(_notify[i])
|
||||
if(_threadId == this_thread::get_id())
|
||||
{
|
||||
delete _notify[i];
|
||||
//同一个线程里面结束, 直接释放相关资源即可
|
||||
CommunicatorEpoll::handleTerminate();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if (_scheduler)
|
||||
{
|
||||
//通知网络线程去释放资源!
|
||||
_epoller->syncCallback(std::bind(&CommunicatorEpoll::handleTerminate, this), 1000);
|
||||
|
||||
// if (_scheduler)
|
||||
// {
|
||||
// _epoller->syncCallback(std::bind(&CommunicatorEpoll::handleTerminate, this), 1000);
|
||||
// LOG_CONSOLE_DEBUG << _scheduler.get() << endl;
|
||||
// }
|
||||
}
|
||||
}
|
||||
_notify[i] = NULL;
|
||||
}
|
||||
|
||||
if(_objectProxyFactory)
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::handleTerminate()
|
||||
{
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
if (_scheduler)
|
||||
{
|
||||
delete _objectProxyFactory;
|
||||
_objectProxyFactory = NULL;
|
||||
for (size_t i = 0; i < MAX_CLIENT_NOTIFYEVENT_NUM; ++i)
|
||||
{
|
||||
if (_notify[i])
|
||||
{
|
||||
delete _notify[i];
|
||||
}
|
||||
_notify[i] = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _vObjectProxys.size(); i++)
|
||||
{
|
||||
if (_vObjectProxys[i])
|
||||
{
|
||||
delete _vObjectProxys[i];
|
||||
_vObjectProxys[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_vObjectProxys.clear();
|
||||
|
||||
//这里是否还是有临界情况!!??
|
||||
if(_epoller)
|
||||
{
|
||||
//定时任务都删除掉
|
||||
for_each(_timerIds.begin(), _timerIds.end(), [&](int64_t id)
|
||||
{ _epoller->erase(id); });
|
||||
}
|
||||
|
||||
_timerIds.clear();
|
||||
|
||||
//独立启动的才需要释放协程调度器, 复用其他协程是不能停止调度器的!
|
||||
if(!this->isSchedCommunicatorEpoll())
|
||||
{
|
||||
_scheduler->terminate();
|
||||
|
||||
assert(_pSptd);
|
||||
|
||||
_pSptd->_sched.reset();
|
||||
|
||||
ServantProxyThreadData::g_sp.reset();
|
||||
}
|
||||
|
||||
_scheduler.reset();
|
||||
|
||||
StatReport::MapStatMicMsg *pmStatMicMsg = NULL;
|
||||
|
||||
while (_statQueue.pop_front(pmStatMicMsg))
|
||||
{
|
||||
assert(pmStatMicMsg != NULL);
|
||||
delete pmStatMicMsg;
|
||||
pmStatMicMsg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::terminate()
|
||||
{
|
||||
_terminate = true;
|
||||
|
||||
//通知epoll响应
|
||||
_terminateFDInfo.notify.notify();
|
||||
//通知网络线程退出, 不再执行任何操作
|
||||
notifyTerminate();
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::notifyUpdateEndpoints(const ServantPrx &prx, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive)
|
||||
void CommunicatorEpoll::notifyUpdateEndpoints(ServantProxy *servantProxy, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive)
|
||||
{
|
||||
FDInfo *nfd = new FDInfo();
|
||||
CommunicatorEpoll *ce = this;
|
||||
|
||||
UpdateListInfo *p = new UpdateListInfo();
|
||||
p->prx = prx;
|
||||
p->active = active;
|
||||
p->inactive = inactive;
|
||||
nfd->p = p;
|
||||
|
||||
nfd->notify.init(&_ep);
|
||||
nfd->iType = FDInfo::ET_C_UPDATE_LIST;
|
||||
nfd->notify.add((uint64_t)nfd);
|
||||
_epoller->asyncCallback([=]()
|
||||
{ servantProxy->onNotifyEndpoints(ce, active, inactive); });
|
||||
}
|
||||
|
||||
ObjectProxy * CommunicatorEpoll::getObjectProxy(const string & sObjectProxyName,const string& setName)
|
||||
int CommunicatorEpoll::loadObjectLocator()
|
||||
{
|
||||
return _objectProxyFactory->getObjectProxy(sObjectProxyName,setName);
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
for (size_t i = 0; i < _objNum; i++)
|
||||
{
|
||||
_vObjectProxys[i]->loadLocator();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CommunicatorEpoll::addFd(int fd,FDInfo * info, uint32_t events)
|
||||
ObjectProxy* CommunicatorEpoll::servantToObjectProxy(ServantProxy *servantProxy)
|
||||
{
|
||||
return _ep.add(fd, (uint64_t)info, events);
|
||||
TC_ThreadRLock lock(_servantMutex);
|
||||
|
||||
auto it = _servantObjectProxy.find(servantProxy);
|
||||
if( it != _servantObjectProxy.end())
|
||||
{
|
||||
//当前线程(CommunicatorEpoll)还没有创建出对应的ObjectProxy
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// assert(false);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CommunicatorEpoll::modFd(int fd,FDInfo * info, uint32_t events)
|
||||
ObjectProxy * CommunicatorEpoll::hasObjectProxy(const string & sObjectProxyName,const string& setName)
|
||||
{
|
||||
return _ep.mod(fd, (uint64_t)info, events);
|
||||
TC_LockT<TC_ThreadRecMutex> lock(_objectMutex);
|
||||
|
||||
string tmpObjName = sObjectProxyName + "!" + setName;
|
||||
auto it = _objectProxys.find(tmpObjName);
|
||||
if(it != _objectProxys.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CommunicatorEpoll::delFd(int fd,FDInfo * info, uint32_t events)
|
||||
ObjectProxy * CommunicatorEpoll::createObjectProxy(ServantProxy *servantProxy, const string & sObjectProxyName, const string& setName)
|
||||
{
|
||||
return _ep.del(fd, (uint64_t)info, events);
|
||||
ObjectProxy * pObjectProxy;
|
||||
string tmpObjName = sObjectProxyName + "!" + setName;
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(_objectMutex);
|
||||
|
||||
auto it = _objectProxys.find(tmpObjName);
|
||||
if (it != _objectProxys.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
pObjectProxy = new ObjectProxy(this, servantProxy, sObjectProxyName, setName);
|
||||
|
||||
_objectProxys[tmpObjName] = pObjectProxy;
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
TC_ThreadWLock lock(_vObjectMutex);
|
||||
|
||||
_vObjectProxys.push_back(pObjectProxy);
|
||||
|
||||
_objNum++;
|
||||
}
|
||||
|
||||
{
|
||||
TC_ThreadWLock lock(_servantMutex);
|
||||
|
||||
_servantObjectProxy[servantProxy] = pObjectProxy;
|
||||
}
|
||||
|
||||
return pObjectProxy;
|
||||
}
|
||||
|
||||
//业务线程调用, 通知对应的网络线程醒过来
|
||||
//iSeq业务线程号
|
||||
void CommunicatorEpoll::notify(size_t iSeq, ReqInfoQueue * msgQueue)
|
||||
void CommunicatorEpoll::addFd(AdapterProxy* adapterProxy)
|
||||
{
|
||||
assert(iSeq < MAX_CLIENT_NOTIFYEVENT_NUM);
|
||||
shared_ptr<TC_Epoller::EpollInfo> epollInfo = adapterProxy->trans()->getEpollInfo();
|
||||
|
||||
if(_notify[iSeq] == NULL)
|
||||
epollInfo->cookie(adapterProxy);
|
||||
|
||||
map<uint32_t, TC_Epoller::EpollInfo::EVENT_CALLBACK> callbacks;
|
||||
|
||||
callbacks[EPOLLIN] = std::bind(&CommunicatorEpoll::handleInputImp, this, std::placeholders::_1);
|
||||
callbacks[EPOLLOUT] = std::bind(&CommunicatorEpoll::handleOutputImp, this, std::placeholders::_1);
|
||||
callbacks[EPOLLERR] = std::bind(&CommunicatorEpoll::handleCloseImp, this, std::placeholders::_1);
|
||||
|
||||
epollInfo->registerCallback(callbacks, EPOLLIN|EPOLLOUT);
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::notify(size_t iSeq)
|
||||
{
|
||||
assert(_notify[iSeq] != NULL);
|
||||
|
||||
// LOG_CONSOLE_DEBUG << "iSeq:" << iSeq << ", epollInfo:" << _notify[iSeq]->notify.getEpollInfo() << ", ce:" << this << endl;
|
||||
|
||||
_notify[iSeq]->notify.getEpollInfo()->mod(EPOLLOUT);
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::initNotify(size_t iSeq, const shared_ptr<ReqInfoQueue> &msgQueue)
|
||||
{
|
||||
// if(_notify[iSeq] != NULL)
|
||||
// {
|
||||
// LOG_CONSOLE_DEBUG << "iSeq:" << iSeq << ", " << msgQueue.get() << ", " << _notify[iSeq]->msgQueue.get() << endl;
|
||||
// }
|
||||
// assert(_notify[iSeq] == NULL);
|
||||
|
||||
if (_notify[iSeq] == NULL)
|
||||
{
|
||||
_notify[iSeq] = new FDInfo();
|
||||
_notify[iSeq]->iType = FDInfo::ET_C_NOTIFY;
|
||||
_notify[iSeq]->p =(void*)msgQueue;
|
||||
_notify[iSeq]->iSeq = iSeq;
|
||||
_notify[iSeq]->notify.init(&_ep);
|
||||
_notify[iSeq]->notify.add((uint64_t)_notify[iSeq]);
|
||||
_notify[iSeq]->msgQueue = msgQueue;
|
||||
_notify[iSeq]->iSeq = iSeq;
|
||||
|
||||
_notify[iSeq]->notify.init(_epoller);
|
||||
|
||||
_notify[iSeq]->notify.getEpollInfo()->cookie((void*)_notify[iSeq]);
|
||||
|
||||
map<uint32_t, TC_Epoller::EpollInfo::EVENT_CALLBACK> callbacks;
|
||||
|
||||
callbacks[EPOLLOUT] = std::bind(&CommunicatorEpoll::handleNotify, this, std::placeholders::_1);
|
||||
|
||||
_notify[iSeq]->notify.getEpollInfo()->registerCallback(callbacks, EPOLLIN | EPOLLOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
_notify[iSeq]->notify.notify();
|
||||
_notify[iSeq]->msgQueue = msgQueue;
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::notifyDel(size_t iSeq)
|
||||
bool CommunicatorEpoll::handleCloseImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
|
||||
{
|
||||
assert(iSeq < MAX_CLIENT_NOTIFYEVENT_NUM);
|
||||
if(_notify[iSeq] && NULL != _notify[iSeq]->p)
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
|
||||
|
||||
adapterProxy->trans()->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommunicatorEpoll::handleInputImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
|
||||
{
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
|
||||
|
||||
try
|
||||
{
|
||||
_notify[iSeq]->notify.notify();
|
||||
adapterProxy->trans()->doResponse();
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << "[CommunicatorEpoll::handleInputImp] error:" << e.what() << endl;
|
||||
TLOGTARS("[CommunicatorEpoll::handleInputImp] error:" << e.what() << endl);
|
||||
adapterProxy->addConnExc(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommunicatorEpoll::handleOutputImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
|
||||
{
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
|
||||
AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
|
||||
|
||||
try
|
||||
{
|
||||
adapterProxy->trans()->doRequest();
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << "[CommunicatorEpoll::handleOutputImp] error:" << e.what() << endl;
|
||||
|
||||
TLOGTARS("[CommunicatorEpoll::handleOutputImp] error:" << e.what() << endl);
|
||||
adapterProxy->addConnExc(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::report(StatReport::MapStatMicMsg *pmStatMicMsg)
|
||||
{
|
||||
bool bFlag = _statQueue.push_back(pmStatMicMsg);
|
||||
if(!bFlag)
|
||||
{
|
||||
delete pmStatMicMsg;
|
||||
pmStatMicMsg = NULL;
|
||||
|
||||
TLOGERROR("[StatReport::report: queue full]" << endl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CommunicatorEpoll::handleInputImp(Transceiver * pTransceiver)
|
||||
bool CommunicatorEpoll::popStatMsg(StatReport::MapStatMicMsg* &mStatMsg)
|
||||
{
|
||||
//检查连接是否有错误
|
||||
if(pTransceiver->isConnecting())
|
||||
{
|
||||
int iVal = 0;
|
||||
SOCKET_LEN_TYPE iLen = static_cast<SOCKET_LEN_TYPE>(sizeof(int));
|
||||
if (::getsockopt(pTransceiver->fd(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&iVal), &iLen) == -1 || iVal)
|
||||
{
|
||||
pTransceiver->close();
|
||||
pTransceiver->getAdapterProxy()->addConnExc(true);
|
||||
TLOGERROR("[CommunicatorEpoll::handleInputImp] connect error "
|
||||
<< pTransceiver->getEndpointInfo().getConnectEndpoint()->toString()
|
||||
<< "," << pTransceiver->getAdapterProxy()->getObjProxy()->name()
|
||||
<< ",_connExcCnt=" << pTransceiver->getAdapterProxy()->ConnExcCnt()
|
||||
<< "," << strerror(iVal) << endl);
|
||||
return;
|
||||
}
|
||||
|
||||
pTransceiver->setConnected();
|
||||
}
|
||||
|
||||
pTransceiver->doResponse();
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::handleOutputImp(Transceiver * pTransceiver)
|
||||
{
|
||||
//检查连接是否有错误
|
||||
if(pTransceiver->isConnecting())
|
||||
{
|
||||
int iVal = 0;
|
||||
SOCKET_LEN_TYPE iLen = static_cast<SOCKET_LEN_TYPE>(sizeof(int));
|
||||
if (::getsockopt(pTransceiver->fd(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&iVal), &iLen) == -1 || iVal)
|
||||
{
|
||||
pTransceiver->close();
|
||||
pTransceiver->getAdapterProxy()->addConnExc(true);
|
||||
TLOGERROR("[CommunicatorEpoll::handleOutputImp] connect error "
|
||||
<< pTransceiver->getEndpointInfo().getConnectEndpoint()->toString()
|
||||
<< "," << pTransceiver->getAdapterProxy()->getObjProxy()->name()
|
||||
<< ",_connExcCnt=" << pTransceiver->getAdapterProxy()->ConnExcCnt()
|
||||
<< "," << strerror(iVal) << endl);
|
||||
return;
|
||||
}
|
||||
|
||||
pTransceiver->setConnected();
|
||||
}
|
||||
|
||||
pTransceiver->doRequest();
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::handle(FDInfo * pFDInfo, const epoll_event &ev)
|
||||
{
|
||||
try
|
||||
{
|
||||
assert(pFDInfo != NULL);
|
||||
|
||||
if(FDInfo::ET_C_TERMINATE == pFDInfo->iType)
|
||||
{
|
||||
//结束通知过来
|
||||
return;
|
||||
}
|
||||
else if(FDInfo::ET_C_UPDATE_LIST == pFDInfo->iType)
|
||||
{
|
||||
UpdateListInfo *p = (UpdateListInfo*)pFDInfo->p;
|
||||
|
||||
assert(p && p->prx);
|
||||
|
||||
p->prx->onNotifyEndpoints(_netThreadSeq, p->active, p->inactive, false);
|
||||
|
||||
pFDInfo->notify.release();
|
||||
|
||||
delete p;
|
||||
delete pFDInfo;
|
||||
|
||||
return;
|
||||
}
|
||||
else if(FDInfo::ET_C_NOTIFY == pFDInfo->iType)
|
||||
{
|
||||
//队列有消息通知过来
|
||||
ReqInfoQueue * pInfoQueue=(ReqInfoQueue*)pFDInfo->p;
|
||||
ReqMessage * msg = NULL;
|
||||
|
||||
size_t maxProcessCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
while(pInfoQueue->pop_front(msg))
|
||||
{
|
||||
//线程退出了
|
||||
if(ReqMessage::THREAD_EXIT == msg->eType)
|
||||
{
|
||||
assert(pInfoQueue->empty());
|
||||
|
||||
size_t iSeq = pFDInfo->iSeq;
|
||||
|
||||
_notify[iSeq]->notify.release();
|
||||
|
||||
_notify[iSeq]->p = NULL;
|
||||
|
||||
delete _notify[iSeq];
|
||||
|
||||
_notify[iSeq] = NULL;
|
||||
|
||||
//delete msg
|
||||
delete msg;
|
||||
|
||||
//delete queue
|
||||
delete pInfoQueue;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
msg->pObjectProxy->invoke(msg);
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
|
||||
if(++maxProcessCount > 1000)
|
||||
{
|
||||
//避免包太多的时候, 循环占用网路线程, 导致连接都建立不上, 一个包都无法发送出去
|
||||
pFDInfo->notify.notify();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Transceiver *pTransceiver = (Transceiver*)pFDInfo->p;
|
||||
|
||||
//连接出错 直接关闭连接
|
||||
if(TC_Epoller::errorEvent(ev))
|
||||
{
|
||||
try
|
||||
{
|
||||
pTransceiver->close();
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//先收包
|
||||
if(TC_Epoller::readEvent(ev))
|
||||
{
|
||||
try
|
||||
{
|
||||
handleInputImp(pTransceiver);
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
}
|
||||
|
||||
//发包
|
||||
if(TC_Epoller::writeEvent(ev))
|
||||
{
|
||||
try
|
||||
{
|
||||
handleOutputImp(pTransceiver);
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
|
||||
}
|
||||
return _statQueue.pop_front(mStatMsg);
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::doTimeout()
|
||||
{
|
||||
int64_t iNow = TNOWMS;
|
||||
if(_nextTime > iNow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
//每_timeoutCheckInterval检查一次
|
||||
_nextTime = iNow + _timeoutCheckInterval;
|
||||
|
||||
for(size_t i = 0; i < _objectProxyFactory->getObjNum(); ++i)
|
||||
for(size_t i = 0; i < getObjNum(); ++i)
|
||||
{
|
||||
_objectProxyFactory->getObjectProxy(i)->doTimeout();
|
||||
getObjectProxy(i)->doTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::doStat()
|
||||
{
|
||||
int64_t iNow = TNOW;
|
||||
if(_nextStatTime > iNow)
|
||||
return;
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
//10s上报一次
|
||||
_nextStatTime = iNow + 10;
|
||||
|
||||
if(isFirstNetThread()) {
|
||||
_communicator->doStat();
|
||||
}
|
||||
|
||||
StatReport::MapStatMicMsg mStatMicMsg;
|
||||
|
||||
for(size_t i = 0;i < _objectProxyFactory->getObjNum(); ++i)
|
||||
{
|
||||
_objectProxyFactory->getObjectProxy(i)->mergeStat(mStatMicMsg);
|
||||
}
|
||||
if(isFirstNetThread()) {
|
||||
_communicator->doStat();
|
||||
}
|
||||
|
||||
//有数据才上报
|
||||
if(!mStatMicMsg.empty())
|
||||
{
|
||||
StatReport::MapStatMicMsg* pmStatMicMsg = new StatReport::MapStatMicMsg(mStatMicMsg);
|
||||
_communicator->getStatReport()->report(_netThreadSeq,pmStatMicMsg);
|
||||
}
|
||||
}
|
||||
StatReport::MapStatMicMsg* pmStatMicMsg = new StatReport::MapStatMicMsg();//(mStatMicMsg);
|
||||
|
||||
void CommunicatorEpoll::pushAsyncThreadQueue(ReqMessage * msg)
|
||||
{
|
||||
_communicator->pushAsyncThreadQueue(msg);
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::reConnect(int64_t ms, Transceiver*p)
|
||||
{
|
||||
//如果节点已经存在,则不重复加入
|
||||
for ( auto & item : _reconnect)
|
||||
{
|
||||
if (item.second == p)
|
||||
for(size_t i = 0;i < getObjNum(); ++i)
|
||||
{
|
||||
return;
|
||||
getObjectProxy(i)->mergeStat(*pmStatMicMsg);
|
||||
}
|
||||
|
||||
//有数据才上报
|
||||
if(!pmStatMicMsg->empty())
|
||||
{
|
||||
report(pmStatMicMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pmStatMicMsg;
|
||||
pmStatMicMsg = NULL;
|
||||
}
|
||||
}
|
||||
_reconnect[ms] = p;
|
||||
}
|
||||
|
||||
string CommunicatorEpoll::getResourcesInfo()
|
||||
void CommunicatorEpoll::getResourcesInfo(ostringstream &desc)
|
||||
{
|
||||
ostringstream desc;
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
desc << TC_Common::outfill("index") << _netThreadSeq << endl;
|
||||
if(_communicator->_statReport) {
|
||||
desc << TC_Common::outfill("stat size") << _communicator->_statReport->getQueueSize(_netThreadSeq) << endl;
|
||||
}
|
||||
desc << TC_Common::outfill("obj num") << _objectProxyFactory->getObjNum() << endl;
|
||||
desc << TC_Common::outfill("stat size") << getReportSize() << endl;
|
||||
desc << TC_Common::outfill("obj num") << getObjNum() << endl;
|
||||
|
||||
const static string TAB = " ";
|
||||
for(size_t i = 0; i < _objectProxyFactory->getObjNum(); ++i)
|
||||
for(size_t i = 0; i < getObjNum(); ++i)
|
||||
{
|
||||
desc << TAB << OUT_LINE_TAB(1) << endl;
|
||||
|
||||
desc << TAB << TC_Common::outfill("obj name") << _objectProxyFactory->getObjectProxy(i)->name() << endl;
|
||||
const vector<AdapterProxy*> &adapters = _objectProxyFactory->getObjectProxy(i)->getAdapters();
|
||||
desc << TAB << TC_Common::outfill("obj name") << getObjectProxy(i)->name() << endl;
|
||||
const vector<AdapterProxy*> &adapters = getObjectProxy(i)->getAdapters();
|
||||
|
||||
for(auto adapter : adapters)
|
||||
{
|
||||
desc << TAB << TAB << OUT_LINE_TAB(2) << endl;
|
||||
|
||||
desc << TAB << TAB << TC_Common::outfill("adapter") << adapter->endpoint().getEndpoint().toString() << endl;
|
||||
desc << TAB << TAB << TC_Common::outfill("recv size") << adapter->trans()->getRecvBuffer()->getBufferLength() << endl;
|
||||
desc << TAB << TAB << TC_Common::outfill("send size") << adapter->trans()->getSendBuffer()->getBufferLength() << endl;
|
||||
desc << TAB << TAB << TC_Common::outfill("recv size") << adapter->trans()->getRecvBuffer().getBufferLength() << endl;
|
||||
desc << TAB << TAB << TC_Common::outfill("send size") << adapter->trans()->getSendBuffer().getBufferLength() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::reConnect()
|
||||
void CommunicatorEpoll::doReconnect()
|
||||
{
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
int64_t iNow = TNOWMS;
|
||||
|
||||
set<Transceiver*> does;
|
||||
set<TC_Transceiver*> does;
|
||||
while(!_reconnect.empty())
|
||||
{
|
||||
auto it = _reconnect.begin();
|
||||
|
@ -473,6 +497,7 @@ void CommunicatorEpoll::reConnect()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//一次循环同一个节点只尝试一次重试,以避免多次触发close,导致重连的间隔无效
|
||||
if (does.find(it->second) != does.end())
|
||||
{
|
||||
|
@ -481,57 +506,103 @@ void CommunicatorEpoll::reConnect()
|
|||
else
|
||||
{
|
||||
does.insert(it->second);
|
||||
it->second->reconnect();
|
||||
it->second->connect();
|
||||
_reconnect.erase(it++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::run()
|
||||
bool CommunicatorEpoll::handleNotify(const shared_ptr<TC_Epoller::EpollInfo> &data)
|
||||
{
|
||||
ServantProxyThreadData * pSptd = ServantProxyThreadData::getData();
|
||||
assert(pSptd != NULL);
|
||||
pSptd->_netThreadSeq = (int)_netThreadSeq;
|
||||
assert(_threadId == this_thread::get_id());
|
||||
|
||||
while (!_terminate)
|
||||
// LOG_CONSOLE_DEBUG << endl;
|
||||
|
||||
//队列有消息通知过来
|
||||
FDInfo *pFDInfo = (FDInfo*)data->cookie();
|
||||
|
||||
ReqMessage * msg = NULL;
|
||||
|
||||
size_t maxProcessCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
while (pFDInfo->msgQueue->pop_front(msg))
|
||||
{
|
||||
//考虑到检测超时等的情况 这里就wait100ms吧
|
||||
int num = _ep.wait(100);
|
||||
msg->pObjectProxy->invoke(msg);
|
||||
|
||||
if (_terminate) break;
|
||||
|
||||
//先处理epoll的网络事件
|
||||
for (int i = 0; i < num; ++i)
|
||||
if(++maxProcessCount > 1000)
|
||||
{
|
||||
const epoll_event& ev = _ep.get(i);
|
||||
//避免包太多的时候, 循环占用网路线程, 导致连接都建立不上, 一个包都无法发送出去
|
||||
data->mod(EPOLLOUT);
|
||||
|
||||
uint64_t data = TC_Epoller::getU64(ev);
|
||||
|
||||
if(data == 0) continue; //data非指针, 退出循环
|
||||
|
||||
// int64_t ms = TNOWMS;
|
||||
|
||||
handle((FDInfo*)data, ev);
|
||||
TLOGTARS("[CommunicatorEpoll::handle max process count: " << maxProcessCount << ", fd:" << data->fd() << "]" << endl);
|
||||
break;
|
||||
}
|
||||
|
||||
//处理超时请求
|
||||
doTimeout();
|
||||
|
||||
//数据上报
|
||||
doStat();
|
||||
reConnect();
|
||||
}
|
||||
catch (exception& e)
|
||||
|
||||
if (pFDInfo->msgQueue->empty() && pFDInfo->autoDestroy)
|
||||
{
|
||||
TLOGERROR("[CommunicatorEpoll:run exception:" << e.what() << "]" << endl);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
TLOGERROR("[CommunicatorEpoll:run exception.]" << endl);
|
||||
// LOG_CONSOLE_DEBUG << "iSeq:" << pFDInfo->iSeq << ", fd:" << pFDInfo->notify.notifyFd() << endl;
|
||||
|
||||
delete pFDInfo;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch(exception & e)
|
||||
{
|
||||
TLOGERROR("[CommunicatorEpoll::handleNotify error: " << e.what() << "]"<<endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("[CommunicatorEpoll::handleNotify error]" <<endl);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::initializeEpoller()
|
||||
{
|
||||
_threadId = this_thread::get_id();
|
||||
|
||||
_scheduler = TC_CoroutineScheduler::scheduler();
|
||||
|
||||
assert(_scheduler);
|
||||
|
||||
_epoller = _scheduler->getEpoller();
|
||||
|
||||
auto id1 = _epoller->postRepeated(1000, false, std::bind(&CommunicatorEpoll::doReconnect, this));
|
||||
auto id2 = _epoller->postRepeated(1000 * 5, false, std::bind(&CommunicatorEpoll::doStat, this));
|
||||
auto id3 = _epoller->postRepeated(_timeoutCheckInterval, false, std::bind(&CommunicatorEpoll::doTimeout, this));
|
||||
|
||||
_timerIds = { id1, id2, id3 };
|
||||
|
||||
}
|
||||
|
||||
void CommunicatorEpoll::run()
|
||||
{
|
||||
//注意网络通信器是通过startCoroutine启动的, 因此就在协程中!
|
||||
|
||||
_public = true;
|
||||
|
||||
initializeEpoller();
|
||||
|
||||
_pSptd = ServantProxyThreadData::getData();
|
||||
_pSptd->_sched = _scheduler;
|
||||
|
||||
_netThreadSeq = _pSptd->_reqQNo;
|
||||
|
||||
_epoller->setName("communicator-epoller-public-netseq:" + TC_Common::tostr(_netThreadSeq));
|
||||
|
||||
//关联公有网络通信器
|
||||
auto info = _pSptd->addCommunicatorEpoll(shared_from_this());
|
||||
info->_communicator = this->_communicator;
|
||||
|
||||
//当前线程处于网络线程中!
|
||||
_pSptd->_communicatorEpoll = this;
|
||||
|
||||
_communicator->notifyCommunicatorEpollStart();
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,8 @@ Current::Current(ServantHandle *pServantHandle)
|
|||
, _response(true)
|
||||
, _ret(0)
|
||||
, _reportStat(true)
|
||||
, _traceCall(false)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -45,7 +47,7 @@ Current::~Current()
|
|||
{
|
||||
reportToStat("one_way_client");
|
||||
}
|
||||
else if(!_data->adapter()->isTarsProtocol() && ServerConfig::ReportFlow)
|
||||
else if (!_isTars && ServerConfig::ReportFlow)
|
||||
{
|
||||
//非tars客户端 从服务端上报调用信息
|
||||
reportToStat("not_tars_client");
|
||||
|
@ -135,7 +137,7 @@ void Current::setReportStat(bool bReport)
|
|||
|
||||
const vector<char>& Current::getRequestBuffer() const
|
||||
{
|
||||
if (_data->adapter()->isTarsProtocol())
|
||||
if (_isTars)
|
||||
{
|
||||
return _request.sBuffer;
|
||||
}
|
||||
|
@ -166,11 +168,11 @@ void Current::initialize(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
|||
|
||||
Application *application = (Application*)this->_servantHandle->getApplication();
|
||||
|
||||
_request.sServantName = application->getServantHelper()->getAdapterServant(_data->adapter()->getName());
|
||||
_request.sServantName = application->getServantHelper()->getAdapterServant(_data->adapter()->getName());
|
||||
|
||||
// _request.sServantName = ServantHelperManager::getInstance()->getAdapterServant(_data->adapter()->getName());
|
||||
_isTars = _data->adapter()->isTarsProtocol();
|
||||
|
||||
if (_data->adapter()->isTarsProtocol())
|
||||
if (_isTars)
|
||||
{
|
||||
initialize(_data->buffer());
|
||||
}
|
||||
|
@ -197,7 +199,8 @@ void Current::initialize(const vector<char>& sRecvBuffer)
|
|||
void Current::sendResponse(const char *buff, uint32_t len)
|
||||
{
|
||||
shared_ptr<TC_EpollServer::SendContext> send = _data->createSendContext();
|
||||
send->buffer()->assign(buff, len);
|
||||
// send->buffer()->assign(buff, len);
|
||||
send->buffer()->addBuffer(buff, len);
|
||||
_servantHandle->sendResponse(send);
|
||||
}
|
||||
|
||||
|
@ -214,6 +217,19 @@ void Current::sendResponse(int iRet, const vector<char> &buff)
|
|||
sendResponse(iRet, response, TARS_STATUS(), "");
|
||||
}
|
||||
|
||||
void Current::sendResponse(int iRet, const string &buff)
|
||||
{
|
||||
//单向调用不需要返回
|
||||
if (_request.cPacketType == TARSONEWAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResponsePacket response;
|
||||
response.sBuffer.assign(buff.begin(), buff.end());
|
||||
sendResponse(iRet, response, TARS_STATUS(), "");
|
||||
}
|
||||
|
||||
void Current::sendResponse(int iRet)
|
||||
{
|
||||
ResponsePacket response;
|
||||
|
@ -248,7 +264,7 @@ void Current::sendResponse(int iRet, ResponsePacket &response, const map<string
|
|||
|
||||
Int32 iHeaderLen = 0;
|
||||
|
||||
TarsOutputStream<BufferWriterVector> os;
|
||||
TarsOutputStream<BufferWriter> os;
|
||||
|
||||
//先预留4个字节长度
|
||||
os.writeBuf((const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
@ -276,7 +292,7 @@ void Current::sendResponse(int iRet, ResponsePacket &response, const map<string
|
|||
}
|
||||
else
|
||||
{
|
||||
//tup回应包用请求包的结构(这里和新版本TAF是有区别的)
|
||||
//tup回应包用请求包的结构(这里和新版本TARS是有区别的)
|
||||
RequestPacket tupResponse;
|
||||
|
||||
tupResponse.iRequestId = _request.iRequestId;
|
||||
|
@ -321,9 +337,9 @@ void Current::sendResponse(int iRet, ResponsePacket &response, const map<string
|
|||
|
||||
iHeaderLen = htonl((int)(os.getLength()));
|
||||
|
||||
memcpy(os.getByteBuffer().data(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
memcpy((void*)os.getBuffer(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
|
||||
|
||||
send->buffer()->swap(os.getByteBuffer());
|
||||
send->setBuffer(ProxyProtocol::toBuffer(os));
|
||||
|
||||
_servantHandle->sendResponse(send);
|
||||
|
||||
|
@ -357,5 +373,27 @@ void Current::reportToStat(const string& sObj)
|
|||
}
|
||||
}
|
||||
|
||||
void Current::setTrace(bool traceCall, const string& traceKey)
|
||||
{
|
||||
_traceCall = traceCall;
|
||||
_traceKey = traceKey;
|
||||
}
|
||||
|
||||
bool Current::isTraced() const
|
||||
{
|
||||
return _traceCall;
|
||||
}
|
||||
|
||||
string Current::getTraceKey() const
|
||||
{
|
||||
return _traceKey;
|
||||
}
|
||||
|
||||
bool Current::connectionExists() const
|
||||
{
|
||||
return _data->connectionExists();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
|
|
@ -16,30 +16,29 @@
|
|||
|
||||
#include "servant/EndpointInfo.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/NetworkUtil.h"
|
||||
//#include "servant/NetworkUtil.h"
|
||||
#include "util/tc_socket.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
EndpointInfo::EndpointInfo()
|
||||
{
|
||||
_setDivision.clear();
|
||||
|
||||
memset(&_addr,0,sizeof(_addr));
|
||||
|
||||
// memset(&_addr,0,sizeof(_addr));
|
||||
}
|
||||
|
||||
EndpointInfo::EndpointInfo(const TC_Endpoint &ep, const string &setDivision)
|
||||
: _ep(ep)
|
||||
, _setDivision(setDivision)
|
||||
, _addressSucc(false)
|
||||
// , _addressSucc(false)
|
||||
{
|
||||
_cmpDesc = createCompareDesc();
|
||||
_desc = createDesc();
|
||||
}
|
||||
|
||||
EndpointInfo::EndpointInfo(const EndpointF &ep)
|
||||
: _setDivision(ep.setId), _addressSucc(false)
|
||||
: _setDivision(ep.setId)
|
||||
{
|
||||
_ep.setHost(ep.host);
|
||||
_ep.setPort(ep.port);
|
||||
|
@ -49,22 +48,14 @@ EndpointInfo::EndpointInfo(const EndpointF &ep)
|
|||
_ep.setQos(ep.qos);
|
||||
_ep.setWeight(ep.weight);
|
||||
_ep.setWeightType(ep.weightType);
|
||||
_ep.setAuthType(ep.authType);
|
||||
|
||||
_ep.setAuthType((TC_Endpoint::AUTH_TYPE)ep.authType);
|
||||
|
||||
_cmpDesc = createCompareDesc();
|
||||
_desc = createDesc();
|
||||
|
||||
}
|
||||
|
||||
void EndpointInfo::parseConnectAddress()
|
||||
{
|
||||
if (isConnectIPv6())
|
||||
{
|
||||
TC_Socket::parseAddrWithPort(getConnectEndpoint()->getHost(), getConnectEndpoint()->getPort(), _addr.in6);
|
||||
}
|
||||
else
|
||||
{
|
||||
TC_Socket::parseAddrWithPort(getConnectEndpoint()->getHost(), getConnectEndpoint()->getPort(), _addr.in);
|
||||
}
|
||||
}
|
||||
|
||||
string EndpointInfo::createCompareDesc()
|
||||
{
|
||||
|
@ -74,54 +65,5 @@ string EndpointInfo::createCompareDesc()
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
string EndpointInfo::createDesc() const
|
||||
{
|
||||
return _ep.toString();
|
||||
}
|
||||
|
||||
bool EndpointInfo::operator == (const EndpointInfo& r) const
|
||||
{
|
||||
return (_cmpDesc == r._cmpDesc);
|
||||
}
|
||||
|
||||
bool EndpointInfo::operator < (const EndpointInfo& r) const
|
||||
{
|
||||
return (_cmpDesc < r._cmpDesc);
|
||||
}
|
||||
|
||||
const string &EndpointInfo::host() const
|
||||
{
|
||||
return _ep.getHost();
|
||||
}
|
||||
|
||||
int32_t EndpointInfo::grid() const
|
||||
{
|
||||
return _ep.getGrid();
|
||||
}
|
||||
|
||||
uint16_t EndpointInfo::port() const
|
||||
{
|
||||
return _ep.getPort();
|
||||
}
|
||||
|
||||
bool EndpointInfo::isTcp() const
|
||||
{
|
||||
return _ep.isTcp();
|
||||
}
|
||||
|
||||
//const struct sockaddr_in& EndpointInfo::addr() const
|
||||
//{
|
||||
// return _addr.in;
|
||||
//}
|
||||
|
||||
const struct sockaddr * EndpointInfo::connectAddrPtr() const
|
||||
{
|
||||
return getConnectEndpoint()->isIPv6() ? (struct sockaddr *)&_addr.in6 : (struct sockaddr *)&_addr.in;
|
||||
}
|
||||
|
||||
const string& EndpointInfo::setDivision() const
|
||||
{
|
||||
return _setDivision;
|
||||
}
|
||||
///////////////////////////////////////////////////////////
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/AppCache.h"
|
||||
#include "servant/Application.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/StatReport.h"
|
||||
|
||||
namespace tars
|
||||
|
@ -46,11 +47,13 @@ QueryEpBase::QueryEpBase(Communicator * pComm, bool bFirstNetThread,bool bInterf
|
|||
, _failTimesLimit(3)
|
||||
, _failTimes(0)
|
||||
{
|
||||
_refreshInterval = TC_Common::strto<int>(_communicator->getProperty("refresh-endpoint-interval", "60*1000"));
|
||||
|
||||
if(_refreshInterval < 5*1000)
|
||||
{
|
||||
_refreshInterval = 5 * 1000;
|
||||
}
|
||||
setNoDelete(true);
|
||||
|
||||
_refreshInterval = TC_Common::strto<int>(_communicator->getProperty("refresh-endpoint-interval", "60000"));
|
||||
|
||||
TLOGTARS("[QueryEpBase _refreshInterval:" << _refreshInterval << "]" << endl);
|
||||
}
|
||||
|
||||
void QueryEpBase::callback_findObjectById4All(Int32 ret, const vector<EndpointF>& activeEp, const vector<EndpointF>& inactiveEp)
|
||||
|
@ -140,11 +143,11 @@ int QueryEpBase::setLocatorPrx(QueryFPrx prx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool QueryEpBase::init(const string & sObjName,const string & sLocator,const string& setName)
|
||||
bool QueryEpBase::init(const string & sObjName, const string& setName)
|
||||
{
|
||||
TLOGTARS("[QueryEpBase::init sObjName:" << sObjName << ",sLocator:" << sLocator << ",setName:" << setName << "]" << endl);
|
||||
_locator = _communicator->getProperty("locator");
|
||||
|
||||
_locator = sLocator;
|
||||
TLOGTARS("QueryEpBase::init sObjName:" << sObjName << ", sLocator:" << _locator << ", setName:" << setName << endl);
|
||||
|
||||
_invokeSetId = setName;
|
||||
|
||||
|
@ -197,6 +200,7 @@ void QueryEpBase::setObjName(const string & sObjName)
|
|||
pos = _objName.find_first_of("#");
|
||||
if(pos != string::npos)
|
||||
{
|
||||
_rootServant = false;
|
||||
_objName = _objName.substr(0, pos);
|
||||
}
|
||||
|
||||
|
@ -223,13 +227,15 @@ void QueryEpBase::setObjName(const string & sObjName)
|
|||
setEndpoints(sEndpoints,_activeEndpoints);
|
||||
setEndpoints(sInactiveEndpoints,_inactiveEndpoints);
|
||||
|
||||
if(_activeEndpoints.size()>0)
|
||||
if(!_activeEndpoints.empty())
|
||||
{
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
if(_activeEndpoints.size()>0 || _inactiveEndpoints.size()>0)
|
||||
{
|
||||
// if(!_direct && (!_activeEndpoints.empty() || !_inactiveEndpoints.empty()))
|
||||
if((!_activeEndpoints.empty() || !_inactiveEndpoints.empty()))
|
||||
{
|
||||
//非直接指定端口, 且从cache中能查到服务端口的, 不需要通知所有ObjectProxy更新地址
|
||||
notifyEndpoints(_activeEndpoints,_inactiveEndpoints,true);
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +260,9 @@ vector<string> QueryEpBase::sepEndpoint(const string& sEndpoints)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0 || TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0 || TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
|
||||
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
|
||||
{
|
||||
string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
|
||||
if(!ep.empty()) {
|
||||
|
@ -330,11 +338,10 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & se
|
|||
}
|
||||
|
||||
EndpointInfo epi(ep, sSetDivision);
|
||||
// EndpointInfo epi(ep.getHost(), ep.getPort(), ep.getType(), ep.getGrid(), sSetDivision, ep.getQos(), ep.getWeight(), ep.getWeightType(), ep.getAuthType());
|
||||
|
||||
setEndpoints.insert(epi);
|
||||
}
|
||||
catch (...)
|
||||
catch (exception &ex)
|
||||
{
|
||||
TLOGERROR("[QueryEpBase::setEndpoints parse error,objname:" << _objName << ",endpoint:" << vEndpoints[i] << "]" << endl);
|
||||
}
|
||||
|
@ -359,6 +366,8 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & se
|
|||
|
||||
void QueryEpBase::refreshReg(GetEndpointType type, const string & sName)
|
||||
{
|
||||
onUpdateOutter();
|
||||
|
||||
if(_direct)
|
||||
{
|
||||
return;
|
||||
|
@ -381,8 +390,12 @@ void QueryEpBase::refreshReg(GetEndpointType type, const string & sName)
|
|||
//一定时间不回调就算超时了
|
||||
_requestTimeout = iNow + _timeoutInterval;
|
||||
|
||||
TLOGTARS("[QueryEpBase::refresh,"<<_objName<<"]"<<endl);
|
||||
TLOGTARS("[QueryEpBase::refresh," << _objName << "]" <<endl);
|
||||
|
||||
if(_valid && !_rootServant)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//判断是同步调用还是异步调用
|
||||
//内部请求主控都是异步请求
|
||||
//接口请求主控第一次是同步请求
|
||||
|
@ -408,7 +421,7 @@ void QueryEpBase::refreshReg(GetEndpointType type, const string & sName)
|
|||
case E_STATION:
|
||||
{
|
||||
iRet = _queryFPrx->findObjectByIdInSameStation(_objName,sName,activeEp,inactiveEp, ServerConfig::Context);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case E_SET:
|
||||
{
|
||||
|
@ -457,7 +470,7 @@ void QueryEpBase::refreshReg(GetEndpointType type, const string & sName)
|
|||
{
|
||||
if(ClientConfig::SetOpen || !_invokeSetId.empty())
|
||||
{
|
||||
//指定set调用时,指定set的优先级最高
|
||||
//指定set调用时,指定set的优先级最高
|
||||
string setId = _invokeSetId.empty()?ClientConfig::SetDivision:_invokeSetId;
|
||||
_queryFPrx->async_findObjectByIdInSameSet(this,_objName,setId, ServerConfig::Context);
|
||||
}
|
||||
|
@ -539,9 +552,6 @@ void QueryEpBase::doEndpoints(const vector<EndpointF>& activeEp, const vector<En
|
|||
}
|
||||
|
||||
// taf istcp意思和这里枚举值对应
|
||||
// EndpointInfo::EType type = EndpointInfo::EType(activeEp[i].istcp);
|
||||
// EndpointInfo ep(activeEp[i].host, activeEp[i].port, (TC_Endpoint::EType)activeEp[i].istcp, activeEp[i].grid, activeEp[i].setId, activeEp[i].qos, activeEp[i].weight, activeEp[i].weightType, activeEp[i].authType);
|
||||
|
||||
activeEps.insert(EndpointInfo(activeEp[i]));
|
||||
}
|
||||
|
||||
|
@ -549,9 +559,6 @@ void QueryEpBase::doEndpoints(const vector<EndpointF>& activeEp, const vector<En
|
|||
for (uint32_t i = 0; i < inactiveEp.size(); ++i)
|
||||
{
|
||||
// taf istcp意思和这里枚举值对应
|
||||
// EndpointInfo::EType type = EndpointInfo::EType(inactiveEp[i].istcp);
|
||||
// EndpointInfo ep(inactiveEp[i].host, inactiveEp[i].port, (TC_Endpoint::EType)activeEp[i].istcp, inactiveEp[i].grid, inactiveEp[i].setId, inactiveEp[i].qos, inactiveEp[i].weight, inactiveEp[i].weightType, inactiveEp[i].authType);
|
||||
|
||||
inactiveEps.insert(EndpointInfo(inactiveEp[i]));
|
||||
}
|
||||
|
||||
|
@ -653,8 +660,7 @@ void QueryEpBase::setEndPointToCache(bool bInactive)
|
|||
for (; iter != doEndpoints.end(); ++iter)
|
||||
{
|
||||
//这里的超时时间 只是对服务端有效。这里的值无效。所以默认用3000了
|
||||
TC_Endpoint ep(iter->host(), iter->port(), 3000, iter->type(), iter->grid(), iter->qos(), iter->weight(), iter->getWeightType());
|
||||
ep.setAuthType(iter->authType());
|
||||
TC_Endpoint ep = iter->getEndpoint();
|
||||
|
||||
if (!sEndpoints.empty())
|
||||
{
|
||||
|
@ -688,8 +694,7 @@ void QueryEpBase::setEndPointToCache(bool bInactive)
|
|||
TLOGTARS("[setEndPointToCache,obj:" << _objName << ",invokeSetId:" << _invokeSetId << ",endpoint:" << sEndpoints << "]" << endl);
|
||||
}
|
||||
|
||||
|
||||
EndpointManager::EndpointManager(ObjectProxy * pObjectProxy, Communicator* pComm, const string & sObjName, bool bFirstNetThread,const string& setName)
|
||||
EndpointManager::EndpointManager(ObjectProxy * pObjectProxy, Communicator* pComm, bool bFirstNetThread)
|
||||
: QueryEpBase(pComm, bFirstNetThread, false)
|
||||
,_objectProxy(pObjectProxy)
|
||||
,_lastRoundPosition(0)
|
||||
|
@ -700,7 +705,6 @@ EndpointManager::EndpointManager(ObjectProxy * pObjectProxy, Communicator* pComm
|
|||
,_consistentHash(E_TC_CONHASH_KETAMAHASH)
|
||||
{
|
||||
setNetThreadProcess(true);
|
||||
init(sObjName, _communicator->getProperty("locator"), setName);
|
||||
}
|
||||
|
||||
EndpointManager::~EndpointManager()
|
||||
|
@ -717,31 +721,69 @@ EndpointManager::~EndpointManager()
|
|||
_allProxys.clear();
|
||||
}
|
||||
|
||||
void EndpointManager::onUpdateOutter()
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << this->_objectProxy << ", valid:" << _valid << ", " << _outterUpdate.get() << endl;
|
||||
if(_outterUpdate)
|
||||
{
|
||||
shared_ptr<OutterUpdate> outterUpdate = _outterUpdate;
|
||||
|
||||
updateEndpoints(outterUpdate->active, outterUpdate->inactive);
|
||||
|
||||
_valid = true;
|
||||
|
||||
_outterUpdate.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointManager::updateEndpointsOutter(const set<EndpointInfo> & active, const set<EndpointInfo> & inactive)
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << this->_objectProxy << ", " << active.begin()->desc() << endl;
|
||||
//创新新对象, 避免线程冲突
|
||||
_outterUpdate = std::make_shared<OutterUpdate>();
|
||||
_outterUpdate->active = active;
|
||||
_outterUpdate->inactive = inactive;
|
||||
|
||||
//更新时间
|
||||
_refreshTime = TNOWMS + _refreshInterval;
|
||||
|
||||
// updateEndpoints(active, inactive);
|
||||
}
|
||||
|
||||
void EndpointManager::updateEndpoints(const set<EndpointInfo> & active, const set<EndpointInfo> & inactive)
|
||||
{
|
||||
set<EndpointInfo>::const_iterator iter;
|
||||
map<string,AdapterProxy*>::iterator iterAdapter;
|
||||
TLOGTARS("[EndpointManager::updateEndpoints obj:" << this->_objName << ", active:" << active.size() << ", inactive size:" << inactive.size() << endl);
|
||||
|
||||
pair<map<string,AdapterProxy*>::iterator,bool> result;
|
||||
|
||||
_activeProxys.clear();
|
||||
_regProxys.clear();
|
||||
|
||||
if(!active.empty())
|
||||
{
|
||||
//先把服务都设置为非活跃
|
||||
for (auto iter = _allProxys.begin(); iter != _allProxys.end(); ++iter)
|
||||
{
|
||||
iter->second->setActiveInReg(false);
|
||||
}
|
||||
}
|
||||
|
||||
//更新active
|
||||
iter = active.begin();
|
||||
for(;iter != active.end();++iter)
|
||||
for(auto iter = active.begin(); iter != active.end(); ++iter)
|
||||
{
|
||||
if(!_direct && _weightType == E_STATIC_WEIGHT && iter->weight() <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
iterAdapter = _allProxys.find(iter->cmpDesc());
|
||||
// LOG_CONSOLE_DEBUG << std::this_thread::get_id() << ", allProxys size:" << _allProxys.size() << ", " << iter->cmpDesc() << endl;
|
||||
|
||||
auto iterAdapter = _allProxys.find(iter->cmpDesc());
|
||||
if(iterAdapter == _allProxys.end())
|
||||
{
|
||||
AdapterProxy* ap = new AdapterProxy(_objectProxy, *iter, _communicator);
|
||||
|
||||
result = _allProxys.insert(make_pair(iter->cmpDesc(),ap));
|
||||
assert(result.second);
|
||||
|
||||
iterAdapter = result.first;
|
||||
|
||||
|
@ -760,15 +802,14 @@ void EndpointManager::updateEndpoints(const set<EndpointInfo> & active, const se
|
|||
}
|
||||
|
||||
//更新inactive
|
||||
iter = inactive.begin();
|
||||
for(;iter != inactive.end();++iter)
|
||||
for(auto iter = inactive.begin(); iter != inactive.end(); ++iter)
|
||||
{
|
||||
if(!_direct && _weightType == E_STATIC_WEIGHT && iter->weight() <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
iterAdapter = _allProxys.find(iter->cmpDesc());
|
||||
auto iterAdapter = _allProxys.find(iter->cmpDesc());
|
||||
if(iterAdapter == _allProxys.end())
|
||||
{
|
||||
AdapterProxy* ap = new AdapterProxy(_objectProxy, *iter, _communicator);
|
||||
|
@ -792,7 +833,7 @@ void EndpointManager::updateEndpoints(const set<EndpointInfo> & active, const se
|
|||
|
||||
//_vRegProxys 需要按顺序来 重排
|
||||
_vRegProxys.clear();
|
||||
iterAdapter = _regProxys.begin();
|
||||
auto iterAdapter = _regProxys.begin();
|
||||
for(;iterAdapter != _regProxys.end();++iterAdapter)
|
||||
{
|
||||
_vRegProxys.push_back(iterAdapter->second);
|
||||
|
@ -827,9 +868,9 @@ bool EndpointManager::selectAdapterProxy(ReqMessage * msg,AdapterProxy * & pAdap
|
|||
}
|
||||
|
||||
//如果有hash,则先使用hash策略
|
||||
if (msg->bHash)
|
||||
if (msg->data._hash)
|
||||
{
|
||||
pAdapterProxy = getHashProxy(msg->iHashCode, msg->bConHash);
|
||||
pAdapterProxy = getHashProxy(msg->data._hashCode, msg->data._conHash);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -855,17 +896,19 @@ AdapterProxy * EndpointManager::getNextValidProxy()
|
|||
{
|
||||
if (_activeProxys.empty())
|
||||
{
|
||||
TLOGERROR("[TAF][EndpointManager::getNextValidProxy activeEndpoints is empty][obj:"<<_objName<<"]" << endl);
|
||||
TLOGERROR("[EndpointManager::getNextValidProxy activeEndpoints is empty][obj:"<<_objName<<"]" << endl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vector<AdapterProxy*> conn;
|
||||
vector<AdapterProxy*> conn;
|
||||
|
||||
for(size_t i=0;i<_activeProxys.size();i++)
|
||||
{
|
||||
++_lastRoundPosition;
|
||||
if(_lastRoundPosition >= _activeProxys.size())
|
||||
{
|
||||
_lastRoundPosition = 0;
|
||||
}
|
||||
|
||||
if(_activeProxys[_lastRoundPosition]->checkActive(false))
|
||||
{
|
||||
|
@ -890,6 +933,8 @@ AdapterProxy * EndpointManager::getNextValidProxy()
|
|||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
|
@ -1018,7 +1063,10 @@ AdapterProxy* EndpointManager::getHashProxyForWeight(int64_t hashCode, bool bSta
|
|||
|
||||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1120,7 +1168,10 @@ AdapterProxy* EndpointManager::getConHashProxyForWeight(int64_t hashCode, bool b
|
|||
|
||||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1210,8 +1261,8 @@ void EndpointManager::updateHashProxyWeighted(bool bStatic)
|
|||
}
|
||||
|
||||
size_t iHashStaticWeightSize = vRegProxys.size();
|
||||
map<size_t, int> mIdToWeight;
|
||||
multimap<int, size_t> mWeightToId;
|
||||
map<size_t, int> mIdToWeight;
|
||||
multimap<int, size_t> mWeightToId;
|
||||
size_t iMaxR = 0;
|
||||
size_t iMaxRouterR = 0;
|
||||
|
||||
|
@ -1269,7 +1320,7 @@ void EndpointManager::updateHashProxyWeighted(bool bStatic)
|
|||
_hashStaticRouterCache.push_back(vIndex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TLOGTARS("EndpointManager::updateHashProxyWeighted bStatic:" << bStatic << "|_objName:" << _objName << "|endpoint:" << vRegProxys[i]->endpoint().desc() << "|iWeight:" << vRegProxys[i]->getWeight() << "|iWeightR:" << iWeight << "|iIndex:" << vIndex[i] << endl);
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1466,9 @@ AdapterProxy* EndpointManager::getHashProxyForNormal(int64_t hashCode)
|
|||
|
||||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1514,7 +1567,9 @@ AdapterProxy* EndpointManager::getConHashProxyForNormal(int64_t hashCode)
|
|||
|
||||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1612,7 +1667,9 @@ AdapterProxy* EndpointManager::getWeightedForNormal(bool bStaticWeighted)
|
|||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeWeightProxy[((uint32_t)rand() % iActiveSize)];
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1649,7 +1706,10 @@ AdapterProxy* EndpointManager::getWeightedForNormal(bool bStaticWeighted)
|
|||
|
||||
//所有adapter都有问题 选不到结点,随机找一个重试
|
||||
AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())];
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
|
||||
adapterProxy->resetRetryTime(false);
|
||||
|
||||
//该proxy可能已经被屏蔽,需重新连一次
|
||||
adapterProxy->checkActive(true);
|
||||
|
||||
return adapterProxy;
|
||||
|
@ -1823,7 +1883,7 @@ EndpointThread::EndpointThread(Communicator* pComm, const string & sObjName, Get
|
|||
, _type(type)
|
||||
, _name(sName)
|
||||
{
|
||||
init(sObjName,_communicator->getProperty("locator"));
|
||||
init(sObjName);
|
||||
}
|
||||
|
||||
void EndpointThread::getEndpoints(vector<EndpointInfo> &activeEndPoint, vector<EndpointInfo> &inactiveEndPoint)
|
||||
|
@ -1835,9 +1895,8 @@ void EndpointThread::getEndpoints(vector<EndpointInfo> &activeEndPoint, vector<E
|
|||
}
|
||||
|
||||
{
|
||||
TC_LockT<TC_SpinLock> lock(_mutex);
|
||||
// TC_ThreadLock::Lock lock(_mutex);
|
||||
|
||||
TC_LockT<TC_ThreadMutex> lock(_mutex);
|
||||
|
||||
refreshReg(_type,_name);
|
||||
|
||||
activeEndPoint = _activeEndPoint;
|
||||
|
@ -1855,7 +1914,7 @@ void EndpointThread::getTCEndpoints(vector<TC_Endpoint> &activeEndPoint, vector<
|
|||
|
||||
{
|
||||
|
||||
TC_LockT<TC_SpinLock> lock(_mutex);
|
||||
TC_LockT<TC_ThreadMutex> lock(_mutex);
|
||||
|
||||
refreshReg(_type,_name);
|
||||
|
||||
|
@ -1868,7 +1927,7 @@ void EndpointThread::notifyEndpoints(const set<EndpointInfo> & active,const set<
|
|||
{
|
||||
if(!bSync)
|
||||
{
|
||||
TC_LockT<TC_SpinLock> lock(_mutex);
|
||||
TC_LockT<TC_ThreadMutex> lock(_mutex);
|
||||
|
||||
update(active, inactive);
|
||||
}
|
||||
|
@ -1948,7 +2007,6 @@ void EndpointManagerThread::getEndpointBySet(const string sName, vector<Endpoint
|
|||
|
||||
void EndpointManagerThread::getEndpointByStation(const string sName, vector<EndpointInfo> &activeEndPoint, vector<EndpointInfo> &inactiveEndPoint)
|
||||
{
|
||||
|
||||
EndpointThread * pThread = getEndpointThread(E_STATION,sName);
|
||||
|
||||
pThread->getEndpoints(activeEndPoint,inactiveEndPoint);
|
||||
|
|
|
@ -44,10 +44,12 @@ void TarsException::throwException(int ret, const string& desc)
|
|||
throw TarsServerQueueTimeoutException("server queue timeout exception: ret:" + TC_Common::tostr(ret) + " msg:"+ desc);
|
||||
break;
|
||||
case TARSPROXYCONNECTERR:
|
||||
throw TarsServerQueueTimeoutException("server connection lost: ret:" + TC_Common::tostr(ret) + " msg:"+ desc);
|
||||
throw TarsServerConnectionException("server connection lost: ret:" + TC_Common::tostr(ret) + " msg:"+ desc);
|
||||
break;
|
||||
default:
|
||||
throw TarsServerUnknownException("server unknown exception: ret:" + TC_Common::tostr(ret) + " msg:"+ desc);
|
||||
case TARSINVOKETIMEOUT:
|
||||
throw TarsServerInvokeTimeoutException(desc);
|
||||
default:
|
||||
throw TarsServerUnknownException("server unknown exception: ret:" + TC_Common::tostr(ret) + " msg:"+ desc);
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "util/tc_platform.h"
|
||||
#include "util/tc_port.h"
|
||||
#include "servant/KeepAliveNodeF.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
#include "servant/NetworkUtil.h"
|
||||
#include "servant/Global.h"
|
||||
#include "util/tc_epoller.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "util/tc_port.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace tars;
|
||||
|
||||
int NetworkUtil::createSocket(bool udp, bool isLocal, bool isIpv6)
|
||||
{
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
int domain = (isIpv6 ? PF_INET6 : PF_INET);
|
||||
#else
|
||||
int domain = isLocal ? PF_LOCAL : (isIpv6 ? PF_INET6 : PF_INET);
|
||||
#endif
|
||||
|
||||
int type = udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||
|
||||
TC_Socket s;
|
||||
s.createSocket(type, domain);
|
||||
|
||||
if(!udp)
|
||||
{
|
||||
s.setTcpNoDelay();
|
||||
s.setKeepAlive();
|
||||
s.setNoCloseWait();
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setRecvBufferSize(512*1024);
|
||||
}
|
||||
|
||||
s.setOwner(false);
|
||||
s.setblock(false);
|
||||
return s.getfd();
|
||||
}
|
||||
|
||||
void NetworkUtil::closeSocketNoThrow(int fd)
|
||||
{
|
||||
TC_Port::closeSocket(fd);
|
||||
}
|
||||
|
||||
bool NetworkUtil::doConnect(int fd, const struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
bool bConnected = false;
|
||||
|
||||
int iRet = ::connect(fd, addr, len);
|
||||
|
||||
if (iRet == 0)
|
||||
{
|
||||
bConnected = true;
|
||||
}
|
||||
else if (!TC_Socket::isInProgress())
|
||||
{
|
||||
closeSocketNoThrow(fd);
|
||||
THROW_EXCEPTION_SYSCODE(TarsNetConnectException, "NetworkUtil::doConnect error");
|
||||
}
|
||||
|
||||
return bConnected;
|
||||
}
|
||||
|
||||
// string NetworkUtil::errorToString(int error)
|
||||
// {
|
||||
// return strerror(error);
|
||||
// }
|
||||
|
||||
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "servant/ObjectProxy.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/Global.h"
|
||||
#include "servant/EndpointManager.h"
|
||||
#include "servant/AppCache.h"
|
||||
|
@ -25,15 +26,15 @@
|
|||
|
||||
namespace tars
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ObjectProxy::ObjectProxy(CommunicatorEpoll * pCommunicatorEpoll, const string & sObjectProxyName,const string& setName)
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
ObjectProxy::ObjectProxy(CommunicatorEpoll *pCommunicatorEpoll, ServantProxy *servantProxy, const string & sObjectProxyName,const string& setName)
|
||||
: _communicatorEpoll(pCommunicatorEpoll)
|
||||
, _sObjectProxyName(sObjectProxyName)
|
||||
, _invokeSetId(setName)
|
||||
, _isInvokeBySet(false)
|
||||
, _hasSetProtocol(false)
|
||||
, _conTimeout(1000)
|
||||
, _servantProxy(NULL)
|
||||
, _servantProxy(servantProxy)
|
||||
{
|
||||
string::size_type pos = sObjectProxyName.find_first_of('@');
|
||||
|
||||
|
@ -62,15 +63,18 @@ ObjectProxy::ObjectProxy(CommunicatorEpoll * pCommunicatorEpoll, const string &
|
|||
_name = _name.substr(0,pos);
|
||||
}
|
||||
|
||||
_proxyProtocol.requestFunc = ProxyProtocol::tarsRequest;
|
||||
_proxyProtocol.responseFunc = ProxyProtocol::tarsResponse;
|
||||
|
||||
_endpointManger.reset(new EndpointManager(this, _communicatorEpoll->getCommunicator(), _sObjectProxyName, _communicatorEpoll->isFirstNetThread(), _invokeSetId));
|
||||
|
||||
}
|
||||
|
||||
ObjectProxy::~ObjectProxy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ObjectProxy::initialize()
|
||||
{
|
||||
_endpointManger.reset(new EndpointManager(this, _communicatorEpoll->getCommunicator(), _communicatorEpoll->isFirstNetThread()));
|
||||
|
||||
_endpointManger->init(_sObjectProxyName, _invokeSetId);
|
||||
}
|
||||
|
||||
const vector<AdapterProxy*> & ObjectProxy::getAdapters()
|
||||
|
@ -102,49 +106,48 @@ int ObjectProxy::loadLocator()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ObjectProxy::setPushCallbacks(const ServantProxyCallbackPtr& cb)
|
||||
{
|
||||
_pushCallback = cb;
|
||||
}
|
||||
|
||||
ServantProxyCallbackPtr ObjectProxy::getPushCallback()
|
||||
{
|
||||
return _pushCallback;
|
||||
}
|
||||
|
||||
void ObjectProxy::setProxyProtocol(const ProxyProtocol& protocol)
|
||||
{
|
||||
if(_hasSetProtocol)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
_hasSetProtocol = true;
|
||||
_proxyProtocol = protocol;
|
||||
}
|
||||
|
||||
ProxyProtocol& ObjectProxy::getProxyProtocol()
|
||||
{
|
||||
return _proxyProtocol;
|
||||
}
|
||||
|
||||
|
||||
void ObjectProxy::setSocketOpt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen)
|
||||
{
|
||||
SocketOpt socketOpt;
|
||||
|
||||
socketOpt.level = level;
|
||||
socketOpt.optname = optname;
|
||||
socketOpt.optval = optval;
|
||||
socketOpt.optlen = optlen;
|
||||
|
||||
_socketOpts.push_back(socketOpt);
|
||||
}
|
||||
|
||||
vector<SocketOpt>& ObjectProxy::getSocketOpt()
|
||||
{
|
||||
return _socketOpts;
|
||||
}
|
||||
//void ObjectProxy::setPushCallbacks(const ServantProxyCallbackPtr& cb)
|
||||
//{
|
||||
// _pushCallback = cb;
|
||||
//}
|
||||
//
|
||||
//ServantProxyCallbackPtr ObjectProxy::getPushCallback()
|
||||
//{
|
||||
// return _pushCallback;
|
||||
//}
|
||||
//
|
||||
//void ObjectProxy::setProxyProtocol(const ProxyProtocol& protocol)
|
||||
//{
|
||||
// if(_hasSetProtocol)
|
||||
// {
|
||||
// return ;
|
||||
// }
|
||||
//
|
||||
// _hasSetProtocol = true;
|
||||
// _proxyProtocol = protocol;
|
||||
//}
|
||||
//
|
||||
//ProxyProtocol& ObjectProxy::getProxyProtocol()
|
||||
//{
|
||||
// return _proxyProtocol;
|
||||
//}
|
||||
//
|
||||
//void ObjectProxy::setSocketOpt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen)
|
||||
//{
|
||||
// SocketOpt socketOpt;
|
||||
//
|
||||
// socketOpt.level = level;
|
||||
// socketOpt.optname = optname;
|
||||
// socketOpt.optval = optval;
|
||||
// socketOpt.optlen = optlen;
|
||||
//
|
||||
// _socketOpts.push_back(socketOpt);
|
||||
//}
|
||||
//
|
||||
//vector<SocketOpt>& ObjectProxy::getSocketOpt()
|
||||
//{
|
||||
// return _socketOpts;
|
||||
//}
|
||||
|
||||
void ObjectProxy::invoke(ReqMessage * msg)
|
||||
{
|
||||
|
@ -180,11 +183,12 @@ void ObjectProxy::invoke(ReqMessage * msg)
|
|||
msg->adapter = pAdapterProxy;
|
||||
|
||||
//连接还没有建立, 暂时先放队列里面
|
||||
if(!msg->adapter->getTransceiver()->hasConnected())
|
||||
if(!msg->adapter->trans()->hasConnected())
|
||||
{
|
||||
bool bRet = _reqTimeoutQueue.push(msg,msg->request.iTimeout+msg->iBeginTime);
|
||||
|
||||
assert(bRet);
|
||||
bool bRet = _reqTimeoutQueue.push(msg, this->_servantProxy->tars_connect_timeout() + msg->iBeginTime);
|
||||
|
||||
assert(bRet);
|
||||
|
||||
//把数据缓存在obj里面
|
||||
TLOGTARS("[ObjectProxy::invoke, " << _name << ", select adapter proxy not connected (have not invoke reg)]" << endl);
|
||||
|
@ -205,8 +209,8 @@ void ObjectProxy::prepareConnection(AdapterProxy *adapterProxy)
|
|||
|
||||
assert(msg != NULL);
|
||||
|
||||
if(msg->adapter == NULL && msg->bHash)
|
||||
// if(msg->adapter != NULL && msg->adapter != adapterProxy)
|
||||
//第一个请求包,adapter必然为NULL,如果需要hash,则重新选择一次
|
||||
if (msg->adapter == NULL && msg->data._hash)
|
||||
{
|
||||
//选取的adapter和之前的不一样(hash的原因), 需要重新选择一个远程服务的Adapter来调用
|
||||
_endpointManger->selectAdapterProxy(msg, adapterProxy);
|
||||
|
@ -237,30 +241,10 @@ void ObjectProxy::onConnect(AdapterProxy *adapterProxy)
|
|||
prepareConnection(adapterProxy);
|
||||
}
|
||||
|
||||
void ObjectProxy::finishInvoke(ReqMessage * msg, AdapterProxy *adapterProxy)
|
||||
{
|
||||
// TLOGERROR("[ObjectProxy::doInvoke,finishInvokeSize, adapter queue size:" << adapterProxy->getTimeoutQueue()->getSendListSize() <<", object queue size:" << _reqTimeoutQueue.size() << ", " << adapterProxy << endl);
|
||||
|
||||
if(getRootServantProxy()->tars_connection_serial() > 0)
|
||||
{
|
||||
prepareConnection(adapterProxy);
|
||||
|
||||
if(!adapterProxy->getTimeoutQueue()->sendListEmpty())
|
||||
{
|
||||
//并行连接模式, 继续发起连接, 建立连接后, 会自动doInvoke发包
|
||||
if(adapterProxy->getTransceiver()->hasConnected()) {
|
||||
adapterProxy->doInvoke(true);
|
||||
}else {
|
||||
adapterProxy->checkActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectProxy::onNotifyEndpoints(const set<EndpointInfo> & active,const set<EndpointInfo> & inactive)
|
||||
{
|
||||
if(_servantProxy) {
|
||||
_servantProxy->onNotifyEndpoints(this->_communicatorEpoll->getCommunicatorEpollId(), active, inactive, true);
|
||||
if(this->getRootServantProxy()) {
|
||||
this->getRootServantProxy()->onNotifyEndpoints(_communicatorEpoll, active, inactive);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,8 +266,6 @@ void ObjectProxy::doInvoke()
|
|||
|
||||
void ObjectProxy::doInvokeException(ReqMessage * msg)
|
||||
{
|
||||
// TLOGTARS("[ObjectProxy::doInvokeException, objname:" << _name << "]" << endl);
|
||||
|
||||
//单向调用出现异常直接删除请求
|
||||
if(msg->eType == ReqMessage::ONE_WAY)
|
||||
{
|
||||
|
@ -296,14 +278,11 @@ void ObjectProxy::doInvokeException(ReqMessage * msg)
|
|||
|
||||
if(msg->eType == ReqMessage::SYNC_CALL)
|
||||
{
|
||||
if(!msg->bCoroFlag)
|
||||
if(!msg->sched)
|
||||
{
|
||||
assert(msg->pMonitor);
|
||||
|
||||
TC_ThreadLock::Lock sync(*(msg->pMonitor));
|
||||
|
||||
msg->pMonitor->notify();
|
||||
msg->bMonitorFin = true;
|
||||
msg->pMonitor->notify();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -315,7 +294,7 @@ void ObjectProxy::doInvokeException(ReqMessage * msg)
|
|||
|
||||
if(msg->callback)
|
||||
{
|
||||
if(!msg->bCoroFlag)
|
||||
if(!msg->sched)
|
||||
{
|
||||
if(msg->callback->getNetThreadProcess())
|
||||
{
|
||||
|
@ -375,6 +354,7 @@ void ObjectProxy::doInvokeException(ReqMessage * msg)
|
|||
void ObjectProxy::doTimeout()
|
||||
{
|
||||
const vector<AdapterProxy*> & vAdapterProxy = _endpointManger->getAdapters();
|
||||
|
||||
for(size_t iAdapter=0; iAdapter< vAdapterProxy.size();++iAdapter)
|
||||
{
|
||||
if(vAdapterProxy[iAdapter] != NULL)
|
||||
|
@ -411,10 +391,13 @@ void ObjectProxy::onSetInactive(const EndpointInfo& ep)
|
|||
const vector<AdapterProxy*> & vAdapterProxy = _endpointManger->getAdapters();
|
||||
for(size_t iAdapter=0; iAdapter< vAdapterProxy.size();++iAdapter)
|
||||
{
|
||||
if(vAdapterProxy[iAdapter] != NULL && vAdapterProxy[iAdapter]->endpoint() == ep)
|
||||
{
|
||||
vAdapterProxy[iAdapter]->onSetInactive();
|
||||
}
|
||||
if(vAdapterProxy[iAdapter] != NULL)
|
||||
{
|
||||
if (vAdapterProxy[iAdapter]->endpoint() == ep)
|
||||
{
|
||||
vAdapterProxy[iAdapter]->onSetInactive();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "servant/ObjectProxyFactory.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
ObjectProxyFactory::ObjectProxyFactory(CommunicatorEpoll * pCommunicatorEpoll)
|
||||
: _communicatorEpoll(pCommunicatorEpoll)
|
||||
, _objNum(0)
|
||||
{
|
||||
}
|
||||
|
||||
ObjectProxyFactory::~ObjectProxyFactory()
|
||||
{
|
||||
for(size_t i = 0; i < _vObjectProxys.size(); i++)
|
||||
{
|
||||
if(_vObjectProxys[i])
|
||||
{
|
||||
delete _vObjectProxys[i];
|
||||
_vObjectProxys[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectProxy * ObjectProxyFactory::getObjectProxy(const string& sObjectProxyName,const string& setName)
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
string tmpObjName = sObjectProxyName + ":" + setName;
|
||||
map<string, ObjectProxy*>::iterator it = _objectProxys.find(tmpObjName);
|
||||
if(it != _objectProxys.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
ObjectProxy * pObjectProxy = new ObjectProxy(_communicatorEpoll, sObjectProxyName,setName);
|
||||
|
||||
_objectProxys[tmpObjName] = pObjectProxy;
|
||||
|
||||
_vObjectProxys.push_back(pObjectProxy);
|
||||
|
||||
_objNum++;
|
||||
|
||||
return pObjectProxy;
|
||||
}
|
||||
|
||||
int ObjectProxyFactory::loadObjectLocator()
|
||||
{
|
||||
TC_LockT<TC_ThreadRecMutex> lock(*this);
|
||||
|
||||
for (size_t i = 0; i < _objNum; i++)
|
||||
{
|
||||
_vObjectProxys[i]->loadLocator();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "servant/ProxyInfo.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "util/tc_base64.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
void ProxyBase::onDisconnect()
|
||||
{
|
||||
setProxyStage(eProxy_Stage_DisConn);
|
||||
}
|
||||
|
||||
void ProxyBase::onConnSuccess()
|
||||
{
|
||||
setProxyStage(eProxy_Stage_Connected);
|
||||
}
|
||||
|
||||
void ProxyBase::setProxyStage(ProxyBase::EMProxyStageType proxyStage)
|
||||
{
|
||||
if (_stage == proxyStage) {
|
||||
return;
|
||||
}
|
||||
|
||||
_stage = proxyStage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
bool ProxySock4::sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst)
|
||||
{
|
||||
//first handshake
|
||||
buff.push_back(kProxy_Sock4_Req1_VN);
|
||||
buff.push_back(kProxy_Sock4_Req1_CD);
|
||||
|
||||
unsigned short nPort = htons(dst.getPort());
|
||||
|
||||
buff.insert(buff.end(), (const char *)&nPort, (const char *)&nPort + sizeof(nPort));
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
TC_Socket::parseAddr(dst.getHost(), addr);
|
||||
|
||||
int32_t tmpLong = addr.s_addr;
|
||||
|
||||
buff.insert(buff.end(), (const char *)&tmpLong, (const char *)&tmpLong + sizeof(tmpLong));
|
||||
|
||||
buff.push_back('a');
|
||||
buff.push_back(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProxySock4::recvProxyPacket(const char *buff, size_t length)
|
||||
{
|
||||
switch (_stage) {
|
||||
case eProxy_Stage_Establish: {
|
||||
//send first handshake
|
||||
if (sizeof(struct sock4ans1) != length) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: Establish protocol length error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sock4ans1 *pSockAns1 = (struct sock4ans1 *) buff;
|
||||
if (pSockAns1->VN != kProxy_Sock4_Ans1_VN || pSockAns1->CD != kProxy_Sock4_Ans1_CD) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: Establish protocol version error: "<< (int)pSockAns1->VN << "," << (int)pSockAns1->CD << "]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
//success
|
||||
onConnSuccess();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ProxySock5::sendProxyPacket(vector<char> & vBuffer, const TC_Endpoint & dst)
|
||||
{
|
||||
switch (_stage) {
|
||||
case eProxy_Stage_DisConn:
|
||||
case eProxy_Stage_Establish: {
|
||||
//first handshake
|
||||
vBuffer.push_back(kProxy_Sock5_Req1_Ver);
|
||||
vBuffer.push_back(kProxy_Sock5_Req1_nMethods);
|
||||
vBuffer.push_back(kProxy_Sock5_Req1_nMethods0);
|
||||
vBuffer.push_back(kProxy_Sock5_Req1_nMethods1);
|
||||
|
||||
return true;
|
||||
}
|
||||
case eProxy_Stage_ACK1: {
|
||||
//second handshake user pwd
|
||||
char nUserLength = (char) _user.size();
|
||||
char nPwdLength = (char) _pass.size();
|
||||
|
||||
vBuffer.push_back(1);
|
||||
vBuffer.push_back(nUserLength);
|
||||
vBuffer.insert(vBuffer.end(), _user.begin(), _user.end());
|
||||
vBuffer.push_back(nPwdLength);
|
||||
vBuffer.insert(vBuffer.end(), _pass.begin(), _pass.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
case eProxy_Stage_ACK2: {
|
||||
//third handshake
|
||||
vBuffer.push_back(kProxy_Sock5_Req3_Ver);
|
||||
vBuffer.push_back(kProxy_Sock5_Req3_Cmd);
|
||||
vBuffer.push_back(kProxy_Sock5_Req3_Rsv);
|
||||
|
||||
if(dst.isIPv6())
|
||||
{
|
||||
vBuffer.push_back(kProxy_Sock5_Req3_AtypIpv6);
|
||||
}
|
||||
else
|
||||
{
|
||||
vBuffer.push_back(kProxy_Sock5_Req3_AtypIpv4);
|
||||
}
|
||||
|
||||
struct in_addr addr;
|
||||
|
||||
TC_Socket::parseAddr(dst.getHost(), addr);
|
||||
|
||||
int32_t tmpLong = addr.s_addr;
|
||||
|
||||
vBuffer.insert(vBuffer.end(), (const char *)&tmpLong, (const char *)&tmpLong + sizeof(tmpLong));
|
||||
|
||||
unsigned short nPort = htons(dst.getPort());
|
||||
vBuffer.insert(vBuffer.end(), (const char *)&nPort, (const char *)&nPort + sizeof(nPort));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProxySock5::recvProxyPacket(const char *buff, size_t length)
|
||||
{
|
||||
switch (_stage) {
|
||||
case eProxy_Stage_Establish: {
|
||||
//send first handshake
|
||||
if (sizeof(struct sock5ans1) != length) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: Establish protocol length error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sock5ans1 *pSock5Ans1 = (struct sock5ans1 *) buff;
|
||||
if (pSock5Ans1->Ver != kProxy_Sock5_Ans1_Ver || (pSock5Ans1->Method != kProxy_Sock5_Ans1_Method_Anonymous
|
||||
&& pSock5Ans1->Method != kProxy_Sock5_Ans1_Method_User)) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: Establish protocol version error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
//need user
|
||||
if (pSock5Ans1->Method == kProxy_Sock5_Ans1_Method_User) {
|
||||
setProxyStage(eProxy_Stage_ACK1);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
//Anonymous
|
||||
setProxyStage(eProxy_Stage_ACK2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case eProxy_Stage_ACK1: {
|
||||
//send second handshake
|
||||
if (sizeof(struct authans) != length) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: ACK1 protocol length error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
struct authans *pSock5Anthans = (struct authans *) buff;
|
||||
if (pSock5Anthans->Ver != kProxy_Sock5_Anthans_Ver
|
||||
|| pSock5Anthans->Status != kProxy_Sock5_Anthans_Status) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: ACK1 protocol version error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
setProxyStage(eProxy_Stage_ACK2);
|
||||
return true;
|
||||
}
|
||||
case eProxy_Stage_ACK2: {
|
||||
if (sizeof(struct sock5ans2) != length) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: ACK2 protocol length error]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
struct sock5ans2 *pSock5An2 = (struct sock5ans2 *) buff;
|
||||
if (pSock5An2->Ver != kProxy_Sock5_Ans2_Ver || pSock5An2->Rep != kProxy_Sock5_Ans2_Rep) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected: ACK2 protocol version error: " << (int)pSock5An2->Ver << "," << (int)pSock5An2->Rep << "]" << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
//success
|
||||
onConnSuccess();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ProxyHttp::sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst)
|
||||
{
|
||||
switch (_stage) {
|
||||
case eProxy_Stage_Establish: {
|
||||
ostringstream oss;
|
||||
//first handshake
|
||||
std::string strRev;
|
||||
if (_user.empty()) {
|
||||
oss << "CONNECT " << dst.getHost() << ":" << dst.getPort()
|
||||
<< " HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\n\r\n";
|
||||
strRev = oss.str();
|
||||
}
|
||||
else {
|
||||
oss << "CONNECT " << dst.getHost() << ":" << dst.getPort()
|
||||
<< " HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\n";
|
||||
|
||||
oss << "Proxy-Authorization:Basic " << TC_Base64::encode(_user + ":" + _pass) << "\r\n\r\n";
|
||||
strRev = oss.str();
|
||||
}
|
||||
|
||||
buff.insert(buff.end(), strRev.begin(), strRev.end());
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProxyHttp::recvProxyPacket(const char *buff, size_t length)
|
||||
{
|
||||
switch (_stage) {
|
||||
case eProxy_Stage_Establish: {
|
||||
TC_HttpResponse rsp;
|
||||
rsp.decode(buff, length);
|
||||
|
||||
//send first handshake
|
||||
if (rsp.getStatus() != 200) {
|
||||
TLOGERROR("[ProxyHttp::recvProxyPacket, proxy disconnected status:" << rsp.getStatus() << ", about:" << rsp.getAbout() << endl);
|
||||
onDisconnect();
|
||||
return false;
|
||||
}
|
||||
//success
|
||||
onConnSuccess();
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -101,42 +101,40 @@ string RemoteConfig::getRemoteFile(const string &sFileName, bool bAppConfigOnly)
|
|||
{
|
||||
if (_configPrx)
|
||||
{
|
||||
string stream;
|
||||
int ret = -1;
|
||||
string stream;
|
||||
int ret = -1;
|
||||
|
||||
for(int i = 0; i < 2;i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_setdivision.empty())
|
||||
{
|
||||
ret = _configPrx->loadConfig(_app, (bAppConfigOnly ? "" : _serverName), sFileName, stream, ServerConfig::Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ConfigInfo confInfo;
|
||||
confInfo.appname = _app;
|
||||
confInfo.servername = (bAppConfigOnly ? "" : _serverName);
|
||||
confInfo.filename = sFileName;
|
||||
confInfo.bAppOnly = bAppConfigOnly;
|
||||
confInfo.setdivision = _setdivision;
|
||||
ret = _configPrx->loadConfigByInfo(confInfo,stream, ServerConfig::Context);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2;i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_setdivision.empty())
|
||||
{
|
||||
ret = _configPrx->loadConfig(_app, (bAppConfigOnly ? "" : _serverName), sFileName, stream, ServerConfig::Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ConfigInfo confInfo;
|
||||
confInfo.appname = _app;
|
||||
confInfo.servername = (bAppConfigOnly ? "" : _serverName);
|
||||
confInfo.filename = sFileName;
|
||||
confInfo.bAppOnly = bAppConfigOnly;
|
||||
confInfo.setdivision = _setdivision;
|
||||
ret = _configPrx->loadConfigByInfo(confInfo,stream, ServerConfig::Context);
|
||||
}
|
||||
|
||||
break;
|
||||
}catch(std::exception& e){
|
||||
//
|
||||
}catch (...){
|
||||
//
|
||||
}
|
||||
}
|
||||
break;
|
||||
}catch(std::exception& e){
|
||||
//
|
||||
}catch (...){
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0 || stream.empty())
|
||||
{
|
||||
throw runtime_error("remote config file is empty:" + sFileName);
|
||||
}
|
||||
|
||||
if (ret != 0 || stream.empty())
|
||||
{
|
||||
throw runtime_error("remote config file is empty:" + sFileName);
|
||||
}
|
||||
|
||||
string newFile = _basePath + FILE_SEP + sFileName + "." + TC_Common::tostr(time(NULL));
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
namespace tars
|
||||
{
|
||||
|
||||
int RollWriteT::_dyeingThread = 0;
|
||||
//int RollWriteT::_dyeingThread = 0;
|
||||
int TimeWriteT::_dyeing = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -93,7 +93,7 @@ void RollWriteT::operator()(ostream &of, const deque<pair<size_t, string> > &ds)
|
|||
}
|
||||
}
|
||||
|
||||
void RollWriteT::setDyeingLogInfo(const string &sApp, const string &sServer, const string & sLogPath, int iMaxSize, int iMaxNum, const CommunicatorPtr &comm, const string &sLogObj)
|
||||
void RollWriteT::setDyeingLogInfo(const string &sApp, const string &sServer, const string & sLogPath, int iMaxSize, int iMaxNum, const LogPrx &logPrx, const string &sLogObj)
|
||||
{
|
||||
_app = sApp;
|
||||
_server = sServer;
|
||||
|
@ -101,17 +101,20 @@ void RollWriteT::setDyeingLogInfo(const string &sApp, const string &sServer, con
|
|||
_maxSize = iMaxSize;
|
||||
_maxNum = iMaxNum;
|
||||
|
||||
if(comm && !sLogObj.empty())
|
||||
{
|
||||
_logPrx = comm->stringToProxy<LogPrx>(sLogObj);
|
||||
//单独设置超时时间
|
||||
_logPrx->tars_timeout(3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LocalRollLogger::~LocalRollLogger()
|
||||
{
|
||||
for(auto e : _logger_ex)
|
||||
{
|
||||
delete e.second;
|
||||
}
|
||||
_logger_ex.clear();
|
||||
}
|
||||
|
||||
void LocalRollLogger::terminate()
|
||||
{
|
||||
if (!_terminate)
|
||||
|
@ -126,6 +129,14 @@ void LocalRollLogger::setLogInfo(const string &sApp, const string &sServer, cons
|
|||
_app = sApp;
|
||||
_server = sServer;
|
||||
_logpath = sLogpath;
|
||||
_logObj = sLogObj;
|
||||
|
||||
if(comm && !sLogObj.empty())
|
||||
{
|
||||
_logPrx = comm->stringToProxy<LogPrx>(sLogObj);
|
||||
//单独设置超时时间
|
||||
_logPrx->tars_timeout(3000);
|
||||
}
|
||||
|
||||
//生成目录
|
||||
TC_File::makeDirRecursive(_logpath + FILE_SEP + _app + FILE_SEP + _server);
|
||||
|
@ -141,7 +152,7 @@ void LocalRollLogger::setLogInfo(const string &sApp, const string &sServer, cons
|
|||
sync(false);
|
||||
|
||||
//设置染色日志信息
|
||||
_logger.getWriteT().setDyeingLogInfo(sApp, sServer, sLogpath, iMaxSize, iMaxNum, comm, sLogObj);
|
||||
_logger.getWriteT().setDyeingLogInfo(sApp, sServer, sLogpath, iMaxSize, iMaxNum, _logPrx, sLogObj);
|
||||
|
||||
}
|
||||
|
||||
|
@ -151,16 +162,72 @@ void LocalRollLogger::sync(bool bSync)
|
|||
if(bSync)
|
||||
{
|
||||
_logger.unSetupThread();
|
||||
}
|
||||
|
||||
TC_ThreadRLock lock(_mutex);
|
||||
for(auto e : _logger_ex)
|
||||
{
|
||||
e.second->unSetupThread();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.setupThread(&_local);
|
||||
|
||||
TC_ThreadRLock lock(_mutex);
|
||||
for(auto e : _logger_ex)
|
||||
{
|
||||
e.second->setupThread(&_local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalRollLogger::enableDyeing(bool bEnable, const string& sDyeingKey/* = ""*/)
|
||||
{
|
||||
_logger.getRoll()->enableDyeing(bEnable, sDyeingKey);
|
||||
|
||||
TC_ThreadRLock lock(_mutex);
|
||||
for(auto e : _logger_ex)
|
||||
{
|
||||
e.second->getRoll()->enableDyeing(bEnable, sDyeingKey);
|
||||
}
|
||||
}
|
||||
|
||||
LocalRollLogger::RollLogger *LocalRollLogger::logger(const string &suffix)
|
||||
{
|
||||
unordered_map<string, RollLogger*>::iterator it;
|
||||
|
||||
{
|
||||
TC_ThreadRLock lock(_mutex);
|
||||
|
||||
it = _logger_ex.find(suffix);
|
||||
|
||||
if (it != _logger_ex.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
TC_ThreadWLock lock(_mutex);
|
||||
it = _logger_ex.find(suffix);
|
||||
|
||||
if (it != _logger_ex.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
RollLogger *logger = new RollLogger();
|
||||
|
||||
//初始化本地循环日志
|
||||
logger->init(_logpath + FILE_SEP + _app + FILE_SEP + _server + FILE_SEP + _app + "." + _server + "." + suffix, _logger.getMaxSize(), _logger.getMaxNum());
|
||||
logger->modFlag(TC_DayLogger::HAS_TIME, false);
|
||||
logger->modFlag(TC_DayLogger::HAS_TIME|TC_DayLogger::HAS_LEVEL|TC_DayLogger::HAS_PID, true);
|
||||
|
||||
//设置染色日志信息
|
||||
logger->getWriteT().setDyeingLogInfo(_app, _server, _logpath, _logger.getMaxSize(), _logger.getMaxSize(), _logPrx, _logObj);
|
||||
|
||||
_logger_ex[suffix] = logger;
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -823,4 +890,49 @@ void RemoteTimeLogger::enableLocalEx(const string &sApp, const string &sServer,c
|
|||
logger(sApp,sServer,sFile)->setRemote(!bEnable);
|
||||
}
|
||||
|
||||
TarsDyeingSwitch::~TarsDyeingSwitch()
|
||||
{
|
||||
if(_needDyeing)
|
||||
{
|
||||
LocalRollLogger::getInstance()->enableDyeing(false);
|
||||
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
if (td)
|
||||
{
|
||||
td->_data._dyeing = false;
|
||||
td->_data._dyeingKey = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TarsDyeingSwitch::getDyeingKey(string & sDyeingkey)
|
||||
{
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
|
||||
if (td && td->_data._dyeing == true)
|
||||
{
|
||||
sDyeingkey = td->_data._dyeingKey;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TarsDyeingSwitch::enableDyeing(const string & sDyeingKey)
|
||||
{
|
||||
LocalRollLogger::getInstance()->enableDyeing(true);
|
||||
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
if(td)
|
||||
|
||||
{
|
||||
td->_data._dyeing = true;
|
||||
td->_data._dyeingKey = sDyeingKey;
|
||||
}
|
||||
_needDyeing = true;
|
||||
_dyeingKey = sDyeingKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#include "servant/KeepAliveNodeF.h"
|
||||
#include "servant/Cookie.h"
|
||||
#include "servant/Application.h"
|
||||
#ifdef TARS_OPENTRACKING
|
||||
#include "servant/text_map_carrier.h"
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// #include "servant/text_map_carrier.h"
|
||||
// #endif
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ namespace tars
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
ServantHandle::ServantHandle(Application *application)
|
||||
: _application(application),_coroSched(NULL)
|
||||
: _application(application)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -60,193 +60,7 @@ ServantHandle::~ServantHandle()
|
|||
++it;
|
||||
}
|
||||
|
||||
if(_coroSched != NULL)
|
||||
{
|
||||
delete _coroSched;
|
||||
_coroSched = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
initialize();
|
||||
|
||||
if (!ServerConfig::OpenCoroutine)
|
||||
{
|
||||
handleImp();
|
||||
}
|
||||
else
|
||||
{
|
||||
//by goodenpei, 判断是否启用顺序模式
|
||||
_bindAdapter->initThreadRecvQueue(getHandleIndex());
|
||||
|
||||
size_t iThreadNum = getEpollServer()->getLogicThreadNum();
|
||||
|
||||
size_t iCoroutineNum = (ServerConfig::CoroutineMemSize > ServerConfig::CoroutineStackSize) ? (ServerConfig::CoroutineMemSize / (ServerConfig::CoroutineStackSize * iThreadNum)) : 1;
|
||||
if (iCoroutineNum < 1) iCoroutineNum = 1;
|
||||
|
||||
startHandle();
|
||||
|
||||
_coroSched = new CoroutineScheduler();
|
||||
_coroSched->init(iCoroutineNum, ServerConfig::CoroutineStackSize);
|
||||
_coroSched->setHandle(this);
|
||||
|
||||
_coroSched->createCoroutine(std::bind(&ServantHandle::handleRequest, this));
|
||||
|
||||
ServantProxyThreadData *pSptd = ServantProxyThreadData::getData();
|
||||
|
||||
assert(pSptd != NULL);
|
||||
|
||||
pSptd->_sched = _coroSched;
|
||||
|
||||
while (!getEpollServer()->isTerminate())
|
||||
{
|
||||
_coroSched->tars_run();
|
||||
}
|
||||
|
||||
_coroSched->terminate();
|
||||
|
||||
_coroSched->destroy();
|
||||
|
||||
stopHandle();
|
||||
}
|
||||
}
|
||||
catch(exception &ex)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::run exception error:" << ex.what() << "]" << endl);
|
||||
cerr << "ServantHandle::run exception error:" << ex.what() << endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::run unknown exception error]" << endl);
|
||||
cerr << "ServantHandle::run unknown exception error]" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::handleRequest()
|
||||
{
|
||||
bool bYield = false;
|
||||
while (!getEpollServer()->isTerminate())
|
||||
{
|
||||
wait();
|
||||
|
||||
//上报心跳
|
||||
heartbeat();
|
||||
|
||||
//为了实现所有主逻辑的单线程化,在每次循环中给业务处理自有消息的机会
|
||||
handleAsyncResponse();
|
||||
handleCustomMessage(true);
|
||||
|
||||
bYield = false;
|
||||
|
||||
shared_ptr<TC_EpollServer::RecvContext> data;
|
||||
try
|
||||
{
|
||||
bool bFlag = true;
|
||||
int iLoop = 100;
|
||||
while (bFlag && iLoop > 0)
|
||||
{
|
||||
--iLoop;
|
||||
if ((_coroSched->getFreeSize() > 0) && popRecvQueue(data))
|
||||
{
|
||||
bYield = true;
|
||||
|
||||
//上报心跳
|
||||
heartbeat();
|
||||
|
||||
//为了实现所有主逻辑的单线程化,在每次循环中给业务处理自有消息的机会
|
||||
handleAsyncResponse();
|
||||
|
||||
//数据已超载 overload
|
||||
if (data->isOverload())
|
||||
{
|
||||
handleOverload(data);
|
||||
}
|
||||
//关闭连接的通知消息
|
||||
else if (data->isClosed())
|
||||
{
|
||||
handleClose(data);
|
||||
}
|
||||
//数据在队列中已经超时了
|
||||
else if ((TNOWMS - data->recvTimeStamp()) > (int64_t)_bindAdapter->getQueueTimeout())
|
||||
{
|
||||
handleTimeout(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t iRet = _coroSched->createCoroutine(std::bind(&ServantHandle::handleRecvData, this, data));
|
||||
if (iRet == 0)
|
||||
{
|
||||
handleOverload(data);
|
||||
}
|
||||
}
|
||||
handleCustomMessage(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//_coroSched->yield();
|
||||
bFlag = false;
|
||||
bYield = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (iLoop == 0) bYield = false;
|
||||
}
|
||||
catch (exception& ex)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
close(data);
|
||||
}
|
||||
|
||||
getEpollServer()->error("[Handle::handleImp] error:" + string(ex.what()));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
close(data);
|
||||
}
|
||||
|
||||
getEpollServer()->error("[Handle::handleImp] unknown error");
|
||||
}
|
||||
if (!bYield)
|
||||
{
|
||||
_coroSched->yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::handleRecvData(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
try
|
||||
{
|
||||
CurrentPtr current = createCurrent(data);
|
||||
|
||||
if (!current)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (current->getBindAdapter()->isTarsProtocol())
|
||||
{
|
||||
handleTarsProtocol(current);
|
||||
}
|
||||
else
|
||||
{
|
||||
handleNoTarsProtocol(current);
|
||||
}
|
||||
}
|
||||
catch(exception &ex)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::handleRecvData exception:" << ex.what() << "]" << endl);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::handleRecvData unknown exception error]" << endl);
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::handleAsyncResponse()
|
||||
|
@ -326,17 +140,17 @@ void ServantHandle::handleCustomMessage(bool bExpectIdle)
|
|||
|
||||
bool ServantHandle::allFilterIsEmpty()
|
||||
{
|
||||
auto it = _servants.begin();
|
||||
auto it = _servants.begin();
|
||||
|
||||
while (it != _servants.end())
|
||||
{
|
||||
if (!it->second->getResponseQueue().empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return true;
|
||||
while (it != _servants.end())
|
||||
{
|
||||
if (!it->second->getResponseQueue().empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServantHandle::initialize()
|
||||
|
@ -400,39 +214,39 @@ void ServantHandle::initialize()
|
|||
|
||||
TC_Common::msleep(100);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::heartbeat()
|
||||
{
|
||||
time_t fcur = TNOW;
|
||||
time_t fcur = TNOW;
|
||||
|
||||
if (abs(fcur - _bindAdapter->getHeartBeatTime()) > HEART_BEAT_INTERVAL)
|
||||
{
|
||||
_bindAdapter->setHeartBeatTime(fcur);
|
||||
if (abs(fcur - _bindAdapter->getHeartBeatTime()) > HEART_BEAT_INTERVAL)
|
||||
{
|
||||
_bindAdapter->setHeartBeatTime(fcur);
|
||||
|
||||
TARS_KEEPALIVE(_bindAdapter->getName());
|
||||
|
||||
//上报连接数 比率
|
||||
if (_bindAdapter->_pReportConRate)
|
||||
{
|
||||
_bindAdapter->_pReportConRate->report((int)(_bindAdapter->getNowConnection() * 1000 / _bindAdapter->getMaxConns()));
|
||||
}
|
||||
//上报连接数 比率
|
||||
if (_bindAdapter->_pReportConRate)
|
||||
{
|
||||
_bindAdapter->_pReportConRate->report((int)(_bindAdapter->getNowConnection() * 1000 / _bindAdapter->getMaxConns()));
|
||||
}
|
||||
|
||||
//有队列, 且队列长度>0才上报
|
||||
if (_bindAdapter->_pReportQueue)
|
||||
{
|
||||
_bindAdapter->_pReportQueue->report((int)_bindAdapter->getRecvBufferSize());
|
||||
}
|
||||
}
|
||||
//有队列, 且队列长度>0才上报
|
||||
if (_bindAdapter->_pReportQueue)
|
||||
{
|
||||
_bindAdapter->_pReportQueue->report((int)_bindAdapter->getRecvBufferSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CurrentPtr ServantHandle::createCurrent(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
CurrentPtr current = new Current(this);
|
||||
CurrentPtr current = new Current(this);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -450,14 +264,14 @@ CurrentPtr ServantHandle::createCurrent(const shared_ptr<TC_EpollServer::RecvCon
|
|||
{
|
||||
int64_t now = TNOWMS;
|
||||
|
||||
//数据在队列中的时间超过了客户端等待的时间(TARS协议)
|
||||
if (current->_request.iTimeout > 0 && (now - data->recvTimeStamp()) > current->_request.iTimeout)
|
||||
{
|
||||
//上报超时数目
|
||||
if(data->adapter()->_pReportTimeoutNum)
|
||||
data->adapter()->_pReportTimeoutNum->report(1);
|
||||
//数据在队列中的时间超过了客户端等待的时间(TARS协议)
|
||||
if (current->_request.iTimeout > 0 && (now - data->recvTimeStamp()) > current->_request.iTimeout)
|
||||
{
|
||||
//上报超时数目
|
||||
if (data->adapter()->_pReportTimeoutNum)
|
||||
data->adapter()->_pReportTimeoutNum->report(1);
|
||||
|
||||
TLOGERROR("[ServantHandle::handle queue timeout:"
|
||||
TLOGERROR("[TARS][ServantHandle::handle queue timeout:"
|
||||
<< current->_request.sServantName << ", func:"
|
||||
<< current->_request.sFuncName << ", recv time:"
|
||||
<< data->recvTimeStamp() << ", queue timeout:"
|
||||
|
@ -467,63 +281,62 @@ CurrentPtr ServantHandle::createCurrent(const shared_ptr<TC_EpollServer::RecvCon
|
|||
|
||||
current->sendResponse(TARSSERVERQUEUETIMEOUT);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
return current;
|
||||
}
|
||||
|
||||
CurrentPtr ServantHandle::createCloseCurrent(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
CurrentPtr current = new Current(this);
|
||||
CurrentPtr current = new Current(this);
|
||||
|
||||
current->initializeClose(data);
|
||||
current->setReportStat(false);
|
||||
current->setCloseType(data->closeType());
|
||||
return current;
|
||||
current->initializeClose(data);
|
||||
current->setReportStat(false);
|
||||
current->setCloseType(data->closeType());
|
||||
return current;
|
||||
}
|
||||
|
||||
void ServantHandle::handleClose(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
TLOGTARS("[ServantHandle::handleClose,adapter:" << data->adapter()->getName() << ",peer:" << data->ip() << ":" << data->port() << "]"<< endl);
|
||||
|
||||
CurrentPtr current = createCloseCurrent(data);
|
||||
CurrentPtr current = createCloseCurrent(data);
|
||||
|
||||
auto sit = _servants.find(current->getServantName());
|
||||
auto sit = _servants.find(current->getServantName());
|
||||
|
||||
if (sit == _servants.end())
|
||||
{
|
||||
TLOGERROR("[ServantHandle::handleClose,adapter:" << data->adapter()->getName()
|
||||
<< ",peer:" << data->ip() << ":" << data->port()<<", " << current->getServantName() << " not found]" << endl);
|
||||
if (sit == _servants.end())
|
||||
{
|
||||
TLOGERROR("[TARS]ServantHandle::handleClose,adapter:" << data->adapter()->getName() << ",peer:" << data->ip() << ":" << data->port() << ", " << current->getServantName() << " not found" << endl);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//业务逻辑处理
|
||||
sit->second->doClose(current);
|
||||
}
|
||||
catch(exception &ex)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::handleClose " << ex.what() << "]" << endl);
|
||||
try
|
||||
{
|
||||
//业务逻辑处理
|
||||
sit->second->doClose(current);
|
||||
}
|
||||
catch (exception& ex)
|
||||
{
|
||||
TLOGERROR("[TARS]ServantHandle::handleClose " << ex.what() << endl);
|
||||
|
||||
return;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
TLOGERROR("[ServantHandle::handleClose unknown error]" << endl);
|
||||
return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
TLOGERROR("[TARS]ServantHandle::handleClose unknown error" << endl);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ServantHandle::handleTimeout(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
CurrentPtr current = createCurrent(data);
|
||||
CurrentPtr current = createCurrent(data);
|
||||
|
||||
if (!current) return;
|
||||
if (!current) return;
|
||||
|
||||
//上报超时数目
|
||||
if(data->adapter()->_pReportTimeoutNum)
|
||||
|
@ -543,9 +356,9 @@ void ServantHandle::handleTimeout(const shared_ptr<TC_EpollServer::RecvContext>
|
|||
|
||||
void ServantHandle::handleOverload(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
CurrentPtr current = createCurrent(data);
|
||||
CurrentPtr current = createCurrent(data);
|
||||
|
||||
if (!current) return;
|
||||
if (!current) return;
|
||||
|
||||
TLOGERROR("[ServantHandle::handleOverload adapter '"
|
||||
<< data->adapter()->getName()
|
||||
|
@ -561,7 +374,7 @@ void ServantHandle::handleOverload(const shared_ptr<TC_EpollServer::RecvContext>
|
|||
|
||||
void ServantHandle::handle(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
||||
{
|
||||
CurrentPtr current = createCurrent(data);
|
||||
CurrentPtr current = createCurrent(data);
|
||||
|
||||
if (!current) return;
|
||||
|
||||
|
@ -576,95 +389,95 @@ void ServantHandle::handle(const shared_ptr<TC_EpollServer::RecvContext> &data)
|
|||
}
|
||||
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
void ServantHandle::processTracking(const TarsCurrentPtr ¤t)
|
||||
{
|
||||
if(!(Application::getCommunicator()->_traceManager))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ServantProxyThreadData * sptd = ServantProxyThreadData::getData();
|
||||
assert(sptd);
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// void ServantHandle::processTracking(const TarsCurrentPtr ¤t)
|
||||
// {
|
||||
// if(!(Application::getCommunicator()->_traceManager))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// ServantProxyThreadData * sptd = ServantProxyThreadData::getData();
|
||||
// assert(sptd);
|
||||
|
||||
if(!sptd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if(!sptd)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
//提取packet中的span信息,更新为被调的span信息后设置到sptd->_trackInfoMap;
|
||||
sptd->_trackInfoMap.clear();
|
||||
// //提取packet中的span信息,更新为被调的span信息后设置到sptd->_trackInfoMap;
|
||||
// sptd->_trackInfoMap.clear();
|
||||
|
||||
if (IS_MSG_TYPE(current->getMessageType(), tars::TARSMESSAGETYPETRACK))
|
||||
{
|
||||
map<string, string>::const_iterator trackinfoIter = current->getRequestStatus().find(ServantProxy::STATUS_TRACK_KEY);
|
||||
TLOGTARS("[TARS] servant got a tracking request, message_type set" << current->getMessageType() << endl);
|
||||
if (trackinfoIter != current->getRequestStatus().end())
|
||||
{
|
||||
TLOGTARS("[TARS] servant got a tracking request, tracking key:" << trackinfoIter->second << endl);
|
||||
string context = trackinfoIter->second;
|
||||
char szBuffer[context.size() + 1];
|
||||
memset(szBuffer, 0x00, context.size() + 1);
|
||||
memcpy(szBuffer, context.c_str(), context.size());
|
||||
// if (IS_MSG_TYPE(current->getMessageType(), tars::TARSMESSAGETYPETRACK))
|
||||
// {
|
||||
// map<string, string>::const_iterator trackinfoIter = current->getRequestStatus().find(ServantProxy::STATUS_TRACK_KEY);
|
||||
// TLOGTARS("[TARS] servant got a tracking request, message_type set" << current->getMessageType() << endl);
|
||||
// if (trackinfoIter != current->getRequestStatus().end())
|
||||
// {
|
||||
// TLOGTARS("[TARS] servant got a tracking request, tracking key:" << trackinfoIter->second << endl);
|
||||
// string context = trackinfoIter->second;
|
||||
// char szBuffer[context.size() + 1];
|
||||
// memset(szBuffer, 0x00, context.size() + 1);
|
||||
// memcpy(szBuffer, context.c_str(), context.size());
|
||||
|
||||
std::unordered_map<std::string, std::string> text_map;
|
||||
write_span_context(text_map, szBuffer);
|
||||
// std::unordered_map<std::string, std::string> text_map;
|
||||
// write_span_context(text_map, szBuffer);
|
||||
|
||||
TextMapCarrier carrier(text_map);
|
||||
auto tracer = Application::getCommunicator()->_traceManager->_tracer;
|
||||
auto span_context_maybe = tracer->Extract(carrier);
|
||||
if(!span_context_maybe)
|
||||
{
|
||||
//error
|
||||
TLOGERROR("[TARS] servant got a tracking request, but extract the span context fail");
|
||||
return ;
|
||||
}
|
||||
// TextMapCarrier carrier(text_map);
|
||||
// auto tracer = Application::getCommunicator()->_traceManager->_tracer;
|
||||
// auto span_context_maybe = tracer->Extract(carrier);
|
||||
// if(!span_context_maybe)
|
||||
// {
|
||||
// //error
|
||||
// TLOGERROR("[TARS] servant got a tracking request, but extract the span context fail");
|
||||
// return ;
|
||||
// }
|
||||
|
||||
string funcName = current->getFuncName();
|
||||
auto child_span = tracer->StartSpan(funcName, {opentracing::ChildOf(span_context_maybe->get())});
|
||||
// string funcName = current->getFuncName();
|
||||
// auto child_span = tracer->StartSpan(funcName, {opentracing::ChildOf(span_context_maybe->get())});
|
||||
|
||||
//text_map.clear();
|
||||
auto err = tracer->Inject(child_span->context(), carrier);
|
||||
assert(err);
|
||||
// //text_map.clear();
|
||||
// auto err = tracer->Inject(child_span->context(), carrier);
|
||||
// assert(err);
|
||||
|
||||
sptd->_trackInfoMap = text_map;
|
||||
// sptd->_trackInfoMap = text_map;
|
||||
|
||||
_spanMap[current->getRequestId()].reset(child_span.release());
|
||||
// _spanMap[current->getRequestId()].reset(child_span.release());
|
||||
|
||||
return ;
|
||||
// return ;
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
|
||||
return ;
|
||||
// return ;
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
void ServantHandle::finishTracking(int ret, const TarsCurrentPtr ¤t)
|
||||
{
|
||||
int requestId = current->getRequestId();
|
||||
// void ServantHandle::finishTracking(int ret, const TarsCurrentPtr ¤t)
|
||||
// {
|
||||
// int requestId = current->getRequestId();
|
||||
|
||||
if(_spanMap.find(requestId) != _spanMap.end())
|
||||
{
|
||||
auto spanIter = _spanMap.find(requestId);
|
||||
spanIter->second->SetTag("Retcode", ret);
|
||||
spanIter->second->Finish();
|
||||
// if(_spanMap.find(requestId) != _spanMap.end())
|
||||
// {
|
||||
// auto spanIter = _spanMap.find(requestId);
|
||||
// spanIter->second->SetTag("Retcode", ret);
|
||||
// spanIter->second->Finish();
|
||||
|
||||
_spanMap.erase(requestId);
|
||||
}
|
||||
}
|
||||
// _spanMap.erase(requestId);
|
||||
// }
|
||||
// }
|
||||
|
||||
#endif
|
||||
// #endif
|
||||
|
||||
bool ServantHandle::processDye(const CurrentPtr ¤t, string& dyeingKey)
|
||||
{
|
||||
//当前线程的线程数据
|
||||
ServantProxyThreadData* sptd = ServantProxyThreadData::getData();
|
||||
//当前线程的线程数据
|
||||
ServantProxyThreadData *sptd = ServantProxyThreadData::getData();
|
||||
|
||||
if (sptd)
|
||||
{
|
||||
sptd->_dyeingKey = "";
|
||||
}
|
||||
if (sptd)
|
||||
{
|
||||
sptd->_data._dyeingKey = "";
|
||||
}
|
||||
|
||||
//当前请求已经被染色, 需要打印染色日志
|
||||
map<string, string>::const_iterator dyeingIt = current->getRequestStatus().find(ServantProxy::STATUS_DYED_KEY);
|
||||
|
@ -698,7 +511,7 @@ bool ServantHandle::processDye(const CurrentPtr ¤t, string& dyeingKey)
|
|||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -718,12 +531,12 @@ bool ServantHandle::processCookie(const CurrentPtr ¤t, map<string, string>
|
|||
|
||||
bool ServantHandle::checkValidSetInvoke(const CurrentPtr ¤t)
|
||||
{
|
||||
/*是否允许检查合法性*/
|
||||
if (ServerConfig::IsCheckSet == 0)
|
||||
{
|
||||
//不检查
|
||||
return true;
|
||||
}
|
||||
/*是否允许检查合法性*/
|
||||
if (ServerConfig::IsCheckSet == 0)
|
||||
{
|
||||
//不检查
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isSetInvoke = IS_MSG_TYPE(current->getMessageType(), tars::TARSMESSAGETYPESETNAME);
|
||||
//客户端按set规则调用且服务端启用set
|
||||
|
@ -743,7 +556,7 @@ bool ServantHandle::checkValidSetInvoke(const CurrentPtr ¤t)
|
|||
{
|
||||
TLOGTARS("[servant got a setname request, setname key:" << setIt->second << "]" << endl);
|
||||
|
||||
sSetName = setIt->second;
|
||||
sSetName = setIt->second;
|
||||
|
||||
if (ClientConfig::SetDivision == sSetName)
|
||||
{
|
||||
|
@ -792,8 +605,8 @@ bool ServantHandle::checkValidSetInvoke(const CurrentPtr ¤t)
|
|||
}
|
||||
}
|
||||
|
||||
//没有按set规则调用
|
||||
return true;
|
||||
//没有按set规则调用
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServantHandle::handleTarsProtocol(const CurrentPtr ¤t)
|
||||
|
@ -807,11 +620,11 @@ void ServantHandle::handleTarsProtocol(const CurrentPtr ¤t)
|
|||
<< current->getRequestId() << "|"
|
||||
<< TC_Common::tostr(current->getRequestStatus()) << "]"<<endl);
|
||||
|
||||
//检查set调用合法性
|
||||
if(!checkValidSetInvoke(current))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//检查set调用合法性
|
||||
if (!checkValidSetInvoke(current))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//处理染色消息
|
||||
string dyeingKey = "";
|
||||
|
@ -821,36 +634,33 @@ void ServantHandle::handleTarsProtocol(const CurrentPtr ¤t)
|
|||
dyeSwitch.enableDyeing(dyeingKey);
|
||||
}
|
||||
|
||||
//处理cookie
|
||||
map<string, string> cookie;
|
||||
CookieOp cookieOp;
|
||||
if (processCookie(current, cookie))
|
||||
{
|
||||
cookieOp.setCookie(cookie);
|
||||
current->setCookie(cookie);
|
||||
}
|
||||
//处理cookie
|
||||
map<string, string> cookie;
|
||||
CookieOp cookieOp;
|
||||
if (processCookie(current, cookie))
|
||||
{
|
||||
cookieOp.setCookie(cookie);
|
||||
current->setCookie(cookie);
|
||||
}
|
||||
// processSample(current);
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
//处理tracking信息
|
||||
processTracking(current);
|
||||
#endif
|
||||
auto sit = _servants.find(current->getServantName());
|
||||
auto sit = _servants.find(current->getServantName());
|
||||
|
||||
if (sit == _servants.end())
|
||||
{
|
||||
current->sendResponse(TARSSERVERNOSERVANTERR);
|
||||
#ifdef TARS_OPENTRACKING
|
||||
finishTracking(TARSSERVERNOSERVANTERR, current);
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// finishTracking(TARSSERVERNOSERVANTERR, current);
|
||||
// #endif
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = TARSSERVERUNKNOWNERR;
|
||||
|
||||
string sResultDesc = "";
|
||||
string sResultDesc = "";
|
||||
|
||||
ResponsePacket response;
|
||||
// vector<char> buffer;
|
||||
|
||||
try
|
||||
{
|
||||
//业务逻辑处理
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,15 +39,10 @@ ServantPrx::element_type* ServantProxyFactory::getServantProxy(const string& nam
|
|||
if(it != _servantProxy.end())
|
||||
return it->second.get();
|
||||
|
||||
ObjectProxy ** ppObjectProxy = new ObjectProxy * [_comm->getClientThreadNum()];
|
||||
assert(ppObjectProxy != NULL);
|
||||
ServantPrx sp = new ServantProxy(_comm, name, setName);
|
||||
|
||||
for(size_t i = 0; i < _comm->getClientThreadNum(); ++i)
|
||||
{
|
||||
ppObjectProxy[i] = _comm->getCommunicatorEpoll(i)->getObjectProxy(name,setName);
|
||||
}
|
||||
|
||||
ServantPrx sp = new ServantProxy(_comm, ppObjectProxy, _comm->getClientThreadNum());
|
||||
//需要主动初始化一次
|
||||
sp->tars_initialize();
|
||||
|
||||
int syncTimeout = TC_Common::strto<int>(_comm->getProperty("sync-invoke-timeout", "3000"));
|
||||
int asyncTimeout = TC_Common::strto<int>(_comm->getProperty("async-invoke-timeout", "5000"));
|
||||
|
|
|
@ -18,31 +18,30 @@
|
|||
#include "util/tc_common.h"
|
||||
#include "util/tc_timeprovider.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/Application.h"
|
||||
#include <iostream>
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include "servant/Application.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
StatReport::StatReport(size_t iEpollNum)
|
||||
: _time(0)
|
||||
StatReport::StatReport(Communicator* communicator)
|
||||
: _communicator(communicator)
|
||||
, _time(0)
|
||||
, _reportInterval(60000)
|
||||
, _reportTimeout(5000)
|
||||
, _maxReportSize(MAX_REPORT_SIZE)
|
||||
, _terminate(false)
|
||||
, _sampleRate(1)
|
||||
, _maxSampleCount(500)
|
||||
, _epollNum(iEpollNum)
|
||||
, _retValueNumLimit(10)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
for(size_t i = 0 ; i < _epollNum; i++)
|
||||
{
|
||||
_statMsg.push_back(new stat_queue(MAX_STAT_QUEUE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
StatReport::~StatReport()
|
||||
|
@ -53,15 +52,6 @@ StatReport::~StatReport()
|
|||
|
||||
getThreadControl().join();
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < _statMsg.size(); ++i)
|
||||
{
|
||||
if(_statMsg[i])
|
||||
{
|
||||
delete _statMsg[i];
|
||||
_statMsg[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StatReport::terminate()
|
||||
|
@ -73,19 +63,6 @@ void StatReport::terminate()
|
|||
notifyAll();
|
||||
}
|
||||
|
||||
void StatReport::report(size_t iSeq,MapStatMicMsg * pmStatMicMsg)
|
||||
{
|
||||
assert(iSeq < _epollNum);
|
||||
bool bFlag = _statMsg[iSeq]->push_back(pmStatMicMsg);
|
||||
if(!bFlag)
|
||||
{
|
||||
delete pmStatMicMsg;
|
||||
pmStatMicMsg = NULL;
|
||||
|
||||
TLOGERROR("[StatReport::report] queue full]" << endl);
|
||||
}
|
||||
}
|
||||
|
||||
void StatReport::setReportInfo(const StatFPrx& statPrx,
|
||||
const PropertyFPrx& propertyPrx,
|
||||
const string& strModuleName,
|
||||
|
@ -387,31 +364,15 @@ void StatReport::report(const string& strMasterName,
|
|||
|
||||
submit(head, body, true);
|
||||
}
|
||||
//
|
||||
//string StatReport::sampleUnid()
|
||||
//{
|
||||
//
|
||||
// static atomic<int> g_id(rand());
|
||||
//
|
||||
// char s[14] = { 0 };
|
||||
// time_t t = TNOW;
|
||||
// int ip = inet_addr(_ip.c_str());
|
||||
// int thread = ++g_id;
|
||||
// static unsigned short n = 0;
|
||||
// ++n;
|
||||
// memcpy(s, &ip, 4);
|
||||
// memcpy(s + 4, &t, 4);
|
||||
// memcpy(s + 8, &thread, 4);
|
||||
// memcpy(s + 12, &n, 2);
|
||||
// return TC_Common::bin2str(string(s, 14));
|
||||
//}
|
||||
|
||||
void StatReport::submit(StatMicMsgHead& head, StatMicMsgBody& body, bool bFromClient)
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
MapStatMicMsg& msg = (bFromClient == true)?_statMicMsgClient:_statMicMsgServer;
|
||||
MapStatMicMsg::iterator it = msg.find( head );
|
||||
|
||||
auto it = msg.find( head );
|
||||
|
||||
if ( it != msg.end() )
|
||||
{
|
||||
StatMicMsgBody& stBody = it->second;
|
||||
|
@ -437,23 +398,6 @@ void StatReport::submit(StatMicMsgHead& head, StatMicMsgBody& body, bool bFromCl
|
|||
}
|
||||
}
|
||||
|
||||
size_t StatReport::getQueueSize(size_t epollIndex)
|
||||
{
|
||||
if(epollIndex >= _statMsg.size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _statMsg[epollIndex]->size();
|
||||
}
|
||||
|
||||
//void StatReport::doSample(const string& strSlaveName,
|
||||
// const string& strInterfaceName,
|
||||
// const string& strSlaveIp,
|
||||
// map<string, string>& status)
|
||||
//{
|
||||
//}
|
||||
|
||||
int StatReport::reportMicMsg(MapStatMicMsg& msg, bool bFromClient)
|
||||
{
|
||||
if (msg.empty()) return 0;
|
||||
|
@ -508,7 +452,7 @@ int StatReport::reportMicMsg(MapStatMicMsg& msg, bool bFromClient)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
catch ( exception& e )
|
||||
catch (exception& e)
|
||||
{
|
||||
TLOGERROR("StatReport::report catch exception:" << e.what() << endl);
|
||||
}
|
||||
|
@ -523,7 +467,7 @@ int StatReport::reportPropMsg()
|
|||
{
|
||||
try
|
||||
{
|
||||
MapStatPropMsg mStatMsg;
|
||||
MapStatPropMsg mStatMsg;
|
||||
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
@ -565,43 +509,43 @@ int StatReport::reportPropMsg()
|
|||
vector<pair<string, string> > v = it->second->get();
|
||||
for(size_t i = 0; i < v.size(); i++)
|
||||
{
|
||||
bool bFlag = false;
|
||||
if(v[i].first == "Sum")
|
||||
{
|
||||
if(v[i].second != "0")
|
||||
bFlag = true;
|
||||
}
|
||||
else if(v[i].first == "Avg")
|
||||
{
|
||||
if(v[i].second != "0")
|
||||
bFlag = true;
|
||||
}
|
||||
else if(v[i].first == "Distr")
|
||||
{
|
||||
if(v[i].second != "")
|
||||
bFlag = true;
|
||||
}
|
||||
else if(v[i].first == "Max")
|
||||
{
|
||||
if(v[i].second != "-9999999")
|
||||
bFlag = true;
|
||||
}
|
||||
else if(v[i].first == "Min")
|
||||
{
|
||||
if(v[i].second != "0")
|
||||
bFlag = true;
|
||||
}
|
||||
else if(v[i].first == "Count")
|
||||
{
|
||||
if(v[i].second != "0")
|
||||
bFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bFlag = true;
|
||||
}
|
||||
// bool bFlag = false;
|
||||
// if(v[i].first == "Sum")
|
||||
// {
|
||||
// if(v[i].second != "0")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else if(v[i].first == "Avg")
|
||||
// {
|
||||
// if(v[i].second != "0")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else if(v[i].first == "Distr")
|
||||
// {
|
||||
// if(v[i].second != "")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else if(v[i].first == "Max")
|
||||
// {
|
||||
// if(v[i].second != "-9999999")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else if(v[i].first == "Min")
|
||||
// {
|
||||
// if(v[i].second != "0")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else if(v[i].first == "Count")
|
||||
// {
|
||||
// if(v[i].second != "0")
|
||||
// bFlag = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// bFlag = true;
|
||||
// }
|
||||
|
||||
if(bFlag)
|
||||
// if(bFlag)
|
||||
{
|
||||
StatPropInfo sp;
|
||||
sp.policy = v[i].first;
|
||||
|
@ -622,42 +566,42 @@ int StatReport::reportPropMsg()
|
|||
}
|
||||
}
|
||||
|
||||
TLOGTARS("[StatReport::reportPropMsg get size:" << mStatMsg.size()<<"]"<< endl);
|
||||
int iLen = 0;
|
||||
MapStatPropMsg mTemp;
|
||||
for(MapStatPropMsg::iterator it = mStatMsg.begin(); it != mStatMsg.end(); it++)
|
||||
{
|
||||
const StatPropMsgHead &head = it->first;
|
||||
const StatPropMsgBody &body = it->second;
|
||||
int iTemLen = head.moduleName.length()+ head.ip.length() + head.propertyName.length() + head.setName.length() + head.setArea.length() + head.setID.length();
|
||||
for(size_t i = 0; i < body.vInfo.size(); i++)
|
||||
{
|
||||
iTemLen+=body.vInfo[i].policy.length();
|
||||
iTemLen+=body.vInfo[i].value.length();
|
||||
}
|
||||
iTemLen = PROPERTY_PROTOCOL_LEN + body.vInfo.size(); //
|
||||
iLen = iLen + iTemLen;
|
||||
if(iLen > _maxReportSize) //不能超过udp 1472
|
||||
{
|
||||
if(_propertyPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportPropMsg send size:" << mTemp.size()<<"]"<< endl);
|
||||
_propertyPrx->tars_set_timeout(_reportTimeout)->async_reportPropMsg(NULL,mTemp);
|
||||
}
|
||||
iLen = iTemLen;
|
||||
mTemp.clear();
|
||||
}
|
||||
mTemp[it->first] = it->second;
|
||||
}
|
||||
if(0 != (int)mTemp.size())
|
||||
{
|
||||
if(_propertyPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportPropMsg send size:" << mTemp.size()<< "]"<< endl);
|
||||
_propertyPrx->tars_set_timeout(_reportTimeout)->async_reportPropMsg(NULL,mTemp);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
TLOGTARS("[StatReport::reportPropMsg get size:" << mStatMsg.size() << "]" << endl);
|
||||
int iLen = 0;
|
||||
MapStatPropMsg mTemp;
|
||||
for (MapStatPropMsg::iterator it = mStatMsg.begin(); it != mStatMsg.end(); it++)
|
||||
{
|
||||
const StatPropMsgHead& head = it->first;
|
||||
const StatPropMsgBody& body = it->second;
|
||||
int iTemLen = head.moduleName.length() + head.ip.length() + head.propertyName.length() + head.setName.length() + head.setArea.length() + head.setID.length();
|
||||
for (size_t i = 0; i < body.vInfo.size(); i++)
|
||||
{
|
||||
iTemLen += body.vInfo[i].policy.length();
|
||||
iTemLen += body.vInfo[i].value.length();
|
||||
}
|
||||
iTemLen = PROPERTY_PROTOCOL_LEN + body.vInfo.size(); //
|
||||
iLen = iLen + iTemLen;
|
||||
if (iLen > _maxReportSize) //不能超过udp 1472
|
||||
{
|
||||
if (_propertyPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportPropMsg send size:" << mTemp.size() << "]" << endl);
|
||||
_propertyPrx->tars_set_timeout(_reportTimeout)->async_reportPropMsg(NULL, mTemp);
|
||||
}
|
||||
iLen = iTemLen;
|
||||
mTemp.clear();
|
||||
}
|
||||
mTemp[it->first] = it->second;
|
||||
}
|
||||
if (0 != (int)mTemp.size())
|
||||
{
|
||||
if (_propertyPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportPropMsg send size:" << mTemp.size() << "]" << endl);
|
||||
_propertyPrx->tars_set_timeout(_reportTimeout)->async_reportPropMsg(NULL, mTemp);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch ( exception& e )
|
||||
{
|
||||
|
@ -670,67 +614,12 @@ int StatReport::reportPropMsg()
|
|||
return -1;
|
||||
}
|
||||
|
||||
int StatReport::reportSampleMsg()
|
||||
{
|
||||
try
|
||||
{
|
||||
MMapStatSampleMsg mmStatSampleMsg;
|
||||
{
|
||||
Lock lock(*this);
|
||||
_statSampleMsg.swap(mmStatSampleMsg);
|
||||
}
|
||||
|
||||
TLOGTARS("[StatReport::reportSampleMsg get size:" << mmStatSampleMsg.size()<<"]"<< endl);
|
||||
|
||||
int iLen = 0;
|
||||
vector<StatSampleMsg> vTemp;
|
||||
for(MMapStatSampleMsg::const_iterator it = mmStatSampleMsg.begin() ;it != mmStatSampleMsg.end();++it)
|
||||
{
|
||||
StatSampleMsg sample = it->second;
|
||||
int iTemLen = STAT_PROTOCOL_LEN +sample.masterName.length() + sample.slaveName.length() + sample.interfaceName.length();
|
||||
iLen = iLen + iTemLen;
|
||||
if(iLen > _maxReportSize) //不能超过udp 1472
|
||||
{
|
||||
if(_statPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportSampleMsg send size:" << vTemp.size()<< "]"<< endl);
|
||||
_statPrx->tars_set_timeout(_reportTimeout)->async_reportSampleMsg(NULL,vTemp, ServerConfig::Context);
|
||||
}
|
||||
iLen = iTemLen;
|
||||
vTemp.clear();
|
||||
}
|
||||
vTemp.push_back(sample);
|
||||
}
|
||||
if(0 != (int)vTemp.size())
|
||||
{
|
||||
if(_statPrx)
|
||||
{
|
||||
TLOGTARS("[StatReport::reportSampleMsg send size:" << vTemp.size()<< "]"<< endl);
|
||||
_statPrx->tars_set_timeout(_reportTimeout)->async_reportSampleMsg(NULL,vTemp, ServerConfig::Context);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch ( exception& e )
|
||||
{
|
||||
TLOGERROR("[StatReport::reportSampleMsg catch exception:" << e.what() << "]" << endl);
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
TLOGERROR("[StatReport::reportSampleMsg catch unkown exception]" << endl);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StatReport::addMicMsg(MapStatMicMsg& old, MapStatMicMsg& add)
|
||||
{
|
||||
MapStatMicMsg::iterator iter;
|
||||
MapStatMicMsg::iterator iterOld;
|
||||
iter = add.begin();
|
||||
auto iter = add.begin();
|
||||
for (; iter != add.end(); ++iter)
|
||||
{
|
||||
iterOld = old.find(iter->first);
|
||||
auto iterOld = old.find(iter->first);
|
||||
if (iterOld == old.end())
|
||||
{
|
||||
//直接insert
|
||||
|
@ -778,20 +667,14 @@ void StatReport::run()
|
|||
{
|
||||
Lock lock(*this);
|
||||
|
||||
if (_terminate)
|
||||
return;
|
||||
|
||||
timedWait(1000);
|
||||
|
||||
if (_terminate)
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
time_t tNow = TNOW;
|
||||
|
||||
if(tNow - _time > _reportInterval/1000)
|
||||
if(tNow - _time >= _reportInterval/1000)
|
||||
{
|
||||
reportMicMsg(_statMicMsgClient, true);
|
||||
|
||||
|
@ -799,10 +682,12 @@ void StatReport::run()
|
|||
|
||||
MapStatMicMsg mStatMsg;
|
||||
|
||||
for(size_t i = 0; i < _epollNum; ++i)
|
||||
auto communicatorEpolls = _communicator->getAllCommunicatorEpoll();
|
||||
|
||||
for(auto ce : communicatorEpolls)
|
||||
{
|
||||
MapStatMicMsg * pStatMsg;
|
||||
while(_statMsg[i]->pop_front(pStatMsg))
|
||||
while(ce->popStatMsg(pStatMsg))
|
||||
{
|
||||
addMicMsg(mStatMsg,*pStatMsg);
|
||||
delete pStatMsg;
|
||||
|
@ -813,7 +698,7 @@ void StatReport::run()
|
|||
|
||||
reportPropMsg();
|
||||
|
||||
reportSampleMsg();
|
||||
// reportSampleMsg();
|
||||
|
||||
_time = tNow;
|
||||
}
|
||||
|
@ -828,6 +713,8 @@ void StatReport::run()
|
|||
TLOGERROR("StatReport::run catch unkown exception" << endl);
|
||||
}
|
||||
}
|
||||
|
||||
ServantProxyThreadData::g_sp.reset();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,900 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#include "servant/Transceiver.h"
|
||||
#include "servant/AdapterProxy.h"
|
||||
#include "servant/Application.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/ProxyInfo.h"
|
||||
|
||||
#if TARS_SSL
|
||||
#include "util/tc_openssl.h"
|
||||
#endif
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
static const int BUFFER_SIZE = 16 * 1024;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
Transceiver::Transceiver(AdapterProxy * pAdapterProxy,const EndpointInfo &ep)
|
||||
: _adapterProxy(pAdapterProxy)
|
||||
, _ep(ep)
|
||||
, _fd(-1)
|
||||
, _connStatus(eUnconnected)
|
||||
, _conTimeoutTime(0)
|
||||
, _authState(AUTH_INIT)
|
||||
, _sendBuffer(this)
|
||||
, _recvBuffer(this)
|
||||
{
|
||||
_fdInfo.iType = FDInfo::ET_C_NET;
|
||||
_fdInfo.p = (void *)this;
|
||||
}
|
||||
|
||||
Transceiver::~Transceiver()
|
||||
{
|
||||
close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Transceiver::checkTimeout()
|
||||
{
|
||||
if(eConnecting == _connStatus && TNOWMS > _conTimeoutTime)
|
||||
{
|
||||
//链接超时
|
||||
TLOGERROR("[Transceiver::checkTimeout ep:"<<_adapterProxy->endpoint().desc()<<" , connect timeout]"<<endl);
|
||||
_adapterProxy->setConTimeout(true);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
bool Transceiver::isSSL() const
|
||||
{
|
||||
return _adapterProxy->endpoint().type() == TC_Endpoint::SSL;
|
||||
}
|
||||
|
||||
void Transceiver::reconnect()
|
||||
{
|
||||
connect();
|
||||
}
|
||||
|
||||
void Transceiver::connect()
|
||||
{
|
||||
if(isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_connStatus == eConnecting || _connStatus == eConnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_proxyPointer = _adapterProxy->getObjProxy()->getRootServantProxy()->getProxyInfo();
|
||||
|
||||
if(_proxyPointer)
|
||||
{
|
||||
_ep.setProxyEndpoint(_proxyPointer->getEndpoint());
|
||||
}
|
||||
|
||||
//每次连接前都重新解析一下地址, 避免dns变了!
|
||||
_ep.parseConnectAddress();
|
||||
|
||||
if (_ep.type() == TC_Endpoint::UDP)
|
||||
{
|
||||
_fd = NetworkUtil::createSocket(true, false, _ep.isConnectIPv6());
|
||||
|
||||
_connStatus = eConnected;
|
||||
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->addFd(_fd, &_fdInfo, EPOLLIN | EPOLLOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fd = NetworkUtil::createSocket(false, false, _ep.isConnectIPv6());
|
||||
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->addFd(_fd, &_fdInfo, EPOLLIN | EPOLLOUT);
|
||||
|
||||
socklen_t len = _ep.isIPv6() ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||
bool bConnected = NetworkUtil::doConnect(_fd, _ep.connectAddrPtr(), len);
|
||||
if(bConnected)
|
||||
{
|
||||
setConnected();
|
||||
}
|
||||
else
|
||||
{
|
||||
_connStatus = Transceiver::eConnecting;
|
||||
_conTimeoutTime = TNOWMS + _adapterProxy->getConTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
TLOGTARS("[Transceiver::connect obj:" << _adapterProxy->getObjProxy()->name()
|
||||
<< ",connect:" << _ep.getConnectEndpoint()->toString() << ", fd:" << _fd << "]" << endl);
|
||||
|
||||
// //设置网络qos的dscp标志
|
||||
// if(0 != _ep.qos())
|
||||
// {
|
||||
// int iQos=_ep.qos();
|
||||
// ::setsockopt(fd,SOL_IP,IP_TOS,&iQos,sizeof(iQos));
|
||||
// }
|
||||
|
||||
//设置套接口选项
|
||||
vector<SocketOpt> &socketOpts = _adapterProxy->getObjProxy()->getSocketOpt();
|
||||
for(size_t i=0; i<socketOpts.size(); ++i)
|
||||
{
|
||||
if(setsockopt(_fd,socketOpts[i].level,socketOpts[i].optname, (const char*)socketOpts[i].optval,socketOpts[i].optlen) == -1)
|
||||
{
|
||||
TLOGERROR("[setsockopt error:" << TC_Exception::parseError(TC_Exception::getSystemCode())
|
||||
<< ",objname:" << _adapterProxy->getObjProxy()->name()
|
||||
<< ",desc:" << _ep.getConnectEndpoint()->toString()
|
||||
<< ",fd:" << _fd
|
||||
<< ",level:" << socketOpts[i].level
|
||||
<< ",optname:" << socketOpts[i].optname
|
||||
<< ",optval:" << socketOpts[i].optval
|
||||
<<" ]"<< endl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Transceiver::setConnected()
|
||||
{
|
||||
_connStatus = eConnected;
|
||||
_adapterProxy->setConTimeout(false);
|
||||
_adapterProxy->addConnExc(false);
|
||||
|
||||
TLOGTARS("[tcp setConnected, " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << "]" << endl);
|
||||
|
||||
if(_proxyPointer)
|
||||
{
|
||||
connectProxy();
|
||||
}
|
||||
else
|
||||
{
|
||||
onSetConnected();
|
||||
}
|
||||
}
|
||||
|
||||
void Transceiver::onSetConnected()
|
||||
{
|
||||
onConnect();
|
||||
|
||||
if(_adapterProxy->getObjProxy()->getPushCallback())
|
||||
{
|
||||
_adapterProxy->getObjProxy()->getPushCallback()->onConnect(*_ep.getConnectEndpoint());
|
||||
}
|
||||
|
||||
_adapterProxy->onConnect();
|
||||
}
|
||||
|
||||
void Transceiver::onConnect()
|
||||
{
|
||||
#if TARS_SSL
|
||||
if (isSSL())
|
||||
{
|
||||
_openssl = _adapterProxy->getObjProxy()->getCommunicatorEpoll()->getCommunicator()->newClientSSL(_adapterProxy->getObjProxy()->getServantProxy()->tars_name());
|
||||
if (!_openssl)
|
||||
{
|
||||
ObjectProxy* obj = _adapterProxy->getObjProxy();
|
||||
TLOGERROR("[onConnect:" << obj->name() << " can't find client SSL_CTX " << endl);
|
||||
this->close();
|
||||
return;
|
||||
}
|
||||
|
||||
_openssl->init(false);
|
||||
|
||||
_openssl->setReadBufferSize(1024 * 8);
|
||||
_openssl->setWriteBufferSize(1024 * 8);
|
||||
|
||||
_openssl->recvBuffer()->setConnection(this);
|
||||
|
||||
int ret = _openssl->doHandshake(_sendBuffer);
|
||||
if (ret != 0)
|
||||
{
|
||||
TLOGERROR(" SSL_connect failed " << endl);
|
||||
this->close();
|
||||
return;
|
||||
}
|
||||
|
||||
// send the encrypt data from write buffer
|
||||
if (!_sendBuffer.empty())
|
||||
{
|
||||
TLOGTARS("[Transceiver::onConnect send handshake:" << _openssl->isHandshaked() << ", send handshake len:" << _sendBuffer.getBufferLength() << endl);
|
||||
|
||||
ret = doRequest();
|
||||
|
||||
if (!isValid())
|
||||
{
|
||||
TLOGERROR("[Transceiver::onConnect send handshake failed, ret:" << ret << endl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
doAuthReq();
|
||||
}
|
||||
|
||||
void Transceiver::connectProxy()
|
||||
{
|
||||
assert(_proxyPointer);
|
||||
|
||||
vector<char> buff;
|
||||
|
||||
_proxyPointer->sendProxyPacket(buff, _ep.getEndpoint());
|
||||
|
||||
TLOGTARS("[Transceiver::connectProxy, size:" << buff.size() << ", proxy:" << _ep.getConnectEndpoint()->toString() << endl);
|
||||
|
||||
_sendBuffer.addBuffer(buff);
|
||||
|
||||
int ret = doRequest();
|
||||
if (!isValid())
|
||||
{
|
||||
TLOGERROR("[Transceiver::connectProxy failed sendRequest to proxy, ret:" << ret << endl);
|
||||
}
|
||||
}
|
||||
|
||||
int Transceiver::doCheckProxy(const char *buff, size_t length)
|
||||
{
|
||||
if(!_proxyPointer || _proxyPointer->isSuccess())
|
||||
return 0;
|
||||
|
||||
bool succ = _proxyPointer->recvProxyPacket(buff, length);
|
||||
if(!succ)
|
||||
{
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!_proxyPointer->isSuccess())
|
||||
{
|
||||
connectProxy();
|
||||
}
|
||||
else
|
||||
{
|
||||
TLOGTARS("[Transceiver::connectProxy, succ]" << endl);
|
||||
|
||||
onSetConnected();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Transceiver::doAuthReq()
|
||||
{
|
||||
ObjectProxy* obj = _adapterProxy->getObjProxy();
|
||||
|
||||
TLOGTARS("[Transceiver::doAuthReq obj:" << obj->name() << ", auth type:" << etos((AUTH_TYPE)_adapterProxy->endpoint().authType()) << endl);
|
||||
|
||||
if (_adapterProxy->endpoint().authType() == AUTH_TYPENONE)
|
||||
{
|
||||
_authState = AUTH_SUCC;
|
||||
TLOGTARS("[Transceiver::doAuthReq doInvoke obj:" << obj->name() << ", auth type:" << etos((AUTH_TYPE)_adapterProxy->endpoint().authType()) << endl);
|
||||
_adapterProxy->doInvoke(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TLOGTARS("[Transceiver::doAuthReq doInvoke obj:" << obj->name() << ", auth type:" << etos((AUTH_TYPE)_adapterProxy->endpoint().authType()) << endl);
|
||||
|
||||
BasicAuthInfo basic;
|
||||
basic.sObjName = obj->name();
|
||||
basic.sAccessKey = obj->getCommunicatorEpoll()->getCommunicator()->getServantProperty(obj->name(), "accesskey");
|
||||
basic.sSecretKey = obj->getCommunicatorEpoll()->getCommunicator()->getServantProperty(obj->name(), "secretkey");
|
||||
|
||||
this->sendAuthData(basic);
|
||||
}
|
||||
}
|
||||
|
||||
void Transceiver::finishInvoke(shared_ptr<ResponsePacket> &rsp)
|
||||
{
|
||||
if (_adapterProxy->endpoint().authType() == AUTH_TYPELOCAL && _authState != AUTH_SUCC)
|
||||
{
|
||||
std::string ret(rsp->sBuffer.begin(), rsp->sBuffer.end());
|
||||
tars::AUTH_STATE tmp = AUTH_SUCC;
|
||||
tars::stoe(ret, tmp);
|
||||
tars::AUTH_STATE newstate = tmp;
|
||||
|
||||
TLOGTARS("[Transceiver::finishInvoke state: " << etos(_authState) << " -> " << etos(newstate) << endl);
|
||||
setAuthState(newstate);
|
||||
|
||||
if (newstate == AUTH_SUCC)
|
||||
{
|
||||
// flush old buffered msg when auth is not complete
|
||||
_adapterProxy->doInvoke(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TLOGERROR("[Transceiver::finishInvoke newstate: " << etos(newstate) << ", error close!" << endl);
|
||||
close();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
_adapterProxy->finishInvoke(rsp);
|
||||
}
|
||||
|
||||
bool Transceiver::sendAuthData(const BasicAuthInfo& info)
|
||||
{
|
||||
assert (_authState != AUTH_SUCC);
|
||||
|
||||
ObjectProxy* objPrx = _adapterProxy->getObjProxy();
|
||||
|
||||
// 走框架的AK/SK认证
|
||||
std::string out = tars::defaultCreateAuthReq(info);
|
||||
|
||||
const int kAuthType = 0x40;
|
||||
RequestPacket request;
|
||||
request.sFuncName = "tarsInnerAuthServer";
|
||||
request.sServantName = "authServant";
|
||||
request.iVersion = TARSVERSION;
|
||||
request.iRequestId = 1;
|
||||
request.cPacketType = TARSNORMAL;
|
||||
request.iMessageType = kAuthType;
|
||||
request.sBuffer.assign(out.begin(), out.end());
|
||||
|
||||
#if TARS_SSL
|
||||
if(this->isSSL()) {
|
||||
vector<char> buff = objPrx->getProxyProtocol().requestFunc(request, this);
|
||||
|
||||
int ret = _openssl->write(buff.data(), (uint32_t) buff.size(), _sendBuffer);
|
||||
if(ret != 0)
|
||||
{
|
||||
TLOGERROR("[Transceiver::sendAuthData ssl write failed, obj:" << _adapterProxy->getObjProxy()->name() << ", error:" << _openssl->getErrMsg() << endl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_sendBuffer.addBuffer(objPrx->getProxyProtocol().requestFunc(request, this));
|
||||
}
|
||||
|
||||
#else
|
||||
_sendBuffer.addBuffer(objPrx->getProxyProtocol().requestFunc(request, this));
|
||||
|
||||
#endif
|
||||
|
||||
TLOGTARS("[sendAuthData:" << objPrx->name() << " len: " << _sendBuffer.getBufferLength() << endl);
|
||||
|
||||
int ret = doRequest();
|
||||
if (!isValid())
|
||||
{
|
||||
TLOGERROR("[Transceiver::sendAuthData failed sendRequest for Auth, ret:" << ret << endl);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Transceiver::close(bool destructor )
|
||||
{
|
||||
if(!isValid()) return;
|
||||
|
||||
if(_proxyPointer)
|
||||
{
|
||||
_proxyPointer->reset();
|
||||
}
|
||||
|
||||
#if TARS_SSL
|
||||
if (_openssl)
|
||||
{
|
||||
_openssl->release();
|
||||
_openssl.reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->delFd(_fd,&_fdInfo, 0);
|
||||
|
||||
TLOGTARS("[Transceiver::close fd:" << _fd << "]" << endl);
|
||||
|
||||
NetworkUtil::closeSocketNoThrow(_fd);
|
||||
|
||||
_connStatus = eUnconnected;
|
||||
|
||||
_fd = -1;
|
||||
|
||||
_sendBuffer.clearBuffers();
|
||||
|
||||
_recvBuffer.clearBuffers();
|
||||
|
||||
_authState = AUTH_INIT;
|
||||
|
||||
//如果从析构函数调用close,则不走以下流程
|
||||
if (!destructor)
|
||||
{
|
||||
if (_adapterProxy->getObjProxy()->getPushCallback())
|
||||
{
|
||||
_adapterProxy->getObjProxy()->getPushCallback()->onClose(*_ep.getConnectEndpoint());
|
||||
}
|
||||
|
||||
int second = _adapterProxy->getObjProxy()->reconnect();
|
||||
if (second > 0)
|
||||
{
|
||||
int64_t nextTryConnectTime = TNOWMS + second * 1000;
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->reConnect(nextTryConnectTime, this);
|
||||
TLOGTARS("[trans close:" << _adapterProxy->getObjProxy()->name() << "," << _ep.getConnectEndpoint()->toString() << ", reconnect:" << second << "]" << endl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Transceiver::doRequest()
|
||||
{
|
||||
if(!isValid()) return -1;
|
||||
|
||||
//buf不为空,先发送buffer的内容
|
||||
while(!_sendBuffer.empty())
|
||||
{
|
||||
auto data = _sendBuffer.getBufferPointer();
|
||||
assert(data.first != NULL && data.second != 0);
|
||||
|
||||
int iRet = this->send(data.first, (uint32_t) data.second, 0);
|
||||
|
||||
if (iRet < 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
_sendBuffer.moveHeader(iRet);
|
||||
}
|
||||
|
||||
//取adapter里面积攒的数据
|
||||
if(_sendBuffer.empty()) {
|
||||
_adapterProxy->doInvoke(false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Transceiver::sendRequest(const shared_ptr<TC_NetWorkBuffer::Buffer> &buff)
|
||||
{
|
||||
//空数据 直接返回成功
|
||||
if(buff->empty()) {
|
||||
return eRetOk;
|
||||
}
|
||||
|
||||
// assert(_sendBuffer.empty());
|
||||
//buf不为空, 表示之前的数据还没发送完, 直接返回失败, 等buffer可写了,epoll会通知写事件
|
||||
if(!_sendBuffer.empty()) {
|
||||
//不应该运行到这里
|
||||
TLOGTARS("[Transceiver::sendRequest should not happened, not empty obj: " << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend;
|
||||
}
|
||||
|
||||
if(eConnected != _connStatus)
|
||||
{
|
||||
TLOGTARS("[Transceiver::sendRequest not connected: " << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend;
|
||||
}
|
||||
|
||||
if(_proxyPointer && !_proxyPointer->isSuccess()) {
|
||||
TLOGTARS("[Transceiver::sendRequest proxy not ok: " << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend;
|
||||
}
|
||||
|
||||
if (_authState != AUTH_SUCC)
|
||||
{
|
||||
#if TARS_SSL
|
||||
if (isSSL() && !_openssl)
|
||||
{
|
||||
TLOGTARS("[Transceiver::sendRequest ssl not created: " << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend;
|
||||
}
|
||||
#endif
|
||||
TLOGTARS("[Transceiver::sendRequest need auth: " << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend; // 需要鉴权但还没通过,不能发送非认证消息
|
||||
}
|
||||
|
||||
#if TARS_SSL
|
||||
// 握手数据已加密,直接发送,会话数据需加密
|
||||
if (isSSL())
|
||||
{
|
||||
if(!_openssl->isHandshaked()) {
|
||||
TLOGTARS("[Transceiver::sendRequest ssl need handshake, obj:" << _adapterProxy->getObjProxy()->name() << endl);
|
||||
return eRetNotSend;
|
||||
}
|
||||
|
||||
int ret = _openssl->write(buff->buffer(), (uint32_t) buff->length(), _sendBuffer);
|
||||
if(ret != 0)
|
||||
{
|
||||
TLOGERROR("[Transceiver::sendRequest ssl write failed, obj:" << _adapterProxy->getObjProxy()->name() << ", error:" << _openssl->getErrMsg() << endl);
|
||||
close();
|
||||
return eRetError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_sendBuffer.addBuffer(buff);
|
||||
}
|
||||
#else
|
||||
_sendBuffer.addBuffer(buff);
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
auto data = _sendBuffer.getBufferPointer();
|
||||
|
||||
int iRet = this->send(data.first, (uint32_t) data.second, 0);
|
||||
if(iRet < 0)
|
||||
{
|
||||
if(!isValid())
|
||||
{
|
||||
_sendBuffer.clearBuffers();
|
||||
TLOGTARS("[Transceiver::sendRequest failed eRetError: data size:" << data.second << "]" << endl);
|
||||
return eRetError;
|
||||
}
|
||||
else
|
||||
{
|
||||
TLOGTARS("[Transceiver::sendRequest failed eRetFull]" << endl);
|
||||
return eRetFull;
|
||||
}
|
||||
}
|
||||
|
||||
_sendBuffer.moveHeader(iRet);
|
||||
}
|
||||
while(!_sendBuffer.empty());
|
||||
|
||||
return eRetOk;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
TcpTransceiver::TcpTransceiver(AdapterProxy * pAdapterProxy, const EndpointInfo &ep)
|
||||
: Transceiver(pAdapterProxy, ep)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int TcpTransceiver::doResponse()
|
||||
{
|
||||
if(!isValid()) return -1;
|
||||
|
||||
int iRet = 0;
|
||||
|
||||
int recvCount = 0;
|
||||
do
|
||||
{
|
||||
char buff[BUFFER_SIZE] = {0x00};
|
||||
|
||||
if ((iRet = this->recv(buff, BUFFER_SIZE, 0)) > 0)
|
||||
{
|
||||
int check = doCheckProxy(buff, iRet);
|
||||
if(check != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TC_NetWorkBuffer *rbuf = &_recvBuffer;
|
||||
#if TARS_SSL
|
||||
if (isSSL())
|
||||
{
|
||||
const bool preHandshake = _openssl->isHandshaked();
|
||||
int ret = _openssl->read(buff, iRet, _sendBuffer);
|
||||
if (ret != 0)
|
||||
{
|
||||
TLOGERROR("[Transceiver::doResponse SSL_read handshake failed: " << _adapterProxy->getObjProxy()->name() << ", info:" << _openssl->getErrMsg() << endl);
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
else if(!_sendBuffer.empty())
|
||||
{
|
||||
TLOGTARS("[Transceiver::doResponse SSL_read prehandshake:" << preHandshake << ", handshake:" << _openssl->isHandshaked() << ", send handshake:" << _sendBuffer.getBufferLength() << endl);
|
||||
|
||||
int ret = doRequest();
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
// doRequest失败 close fd
|
||||
if (!isValid())
|
||||
{
|
||||
TLOGERROR("[Transceiver::doResponse ssl doRequest failed. ret:" << ret << endl);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_openssl->isHandshaked())
|
||||
{
|
||||
TLOGTARS("[Transceiver::doResponse not handshake, prehandshake:" << preHandshake << ", handshake:" << _openssl->isHandshaked() << endl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!preHandshake) {
|
||||
doAuthReq();
|
||||
// doAuthReq失败,会close fd, 这里判断下是否还有效
|
||||
if (!isValid()) {
|
||||
TLOGERROR("[Transceiver::doResponse doAuthReq failed" << endl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TLOGTARS("[Transceiver::doResponse prehandshake:" << preHandshake << ", handshake:" << _openssl->isHandshaked() << endl);
|
||||
}
|
||||
|
||||
rbuf = _openssl->recvBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
rbuf->addBuffer(buff, iRet);
|
||||
}
|
||||
#else
|
||||
rbuf->addBuffer(buff, iRet);
|
||||
#endif
|
||||
++recvCount;
|
||||
|
||||
try
|
||||
{
|
||||
TC_NetWorkBuffer::PACKET_TYPE ret;
|
||||
|
||||
do
|
||||
{
|
||||
shared_ptr<ResponsePacket> rsp = std::make_shared<ResponsePacket>();
|
||||
|
||||
ret = _adapterProxy->getObjProxy()->getProxyProtocol().responseFunc(*rbuf, *rsp.get());
|
||||
|
||||
if (ret == TC_NetWorkBuffer::PACKET_ERR) {
|
||||
TLOGERROR( "[tcp doResponse," << _adapterProxy->getObjProxy()->name() << ", size:" << iRet << ", fd:" << _fd << "," << _ep.getConnectEndpoint()->toString() << ",tcp recv decode error" << endl);
|
||||
close();
|
||||
break;
|
||||
}
|
||||
else if (ret == TC_NetWorkBuffer::PACKET_FULL) {
|
||||
finishInvoke(rsp);
|
||||
}
|
||||
else if (ret == TC_NetWorkBuffer::PACKET_FULL_CLOSE) {
|
||||
close();
|
||||
finishInvoke(rsp);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
while (ret == TC_NetWorkBuffer::PACKET_FULL);
|
||||
|
||||
//接收的数据小于buffer大小, 内核会再次通知你
|
||||
if(iRet < BUFFER_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//收包太多了, 中断一下, 释放线程给send等
|
||||
if (recvCount >= 100 && isValid()) {
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->modFd(_fd, &_fdInfo, EPOLLIN | EPOLLOUT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (exception & ex) {
|
||||
TLOGERROR("[tcp doResponse," << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ","
|
||||
<< _ep.getConnectEndpoint()->toString() << ",tcp recv decode error:" << ex.what() << endl);
|
||||
|
||||
close();
|
||||
}
|
||||
catch (...) {
|
||||
TLOGERROR("[tcp doResponse," << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ","
|
||||
<< _ep.getConnectEndpoint()->toString() << ",tcp recv decode error." << endl);
|
||||
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
while (iRet>0);
|
||||
|
||||
// TLOGTARS("[tcp doResponse, " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ", all recvbuf:" << _recvBuffer.getBufferLength() << "]" << endl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TcpTransceiver::send(const void* buf, uint32_t len, uint32_t flag)
|
||||
{
|
||||
//只有是连接状态才能收发数据
|
||||
if(eConnected != _connStatus)
|
||||
return -1;
|
||||
|
||||
int iRet = ::send(_fd, (const char*)buf, len, flag);
|
||||
|
||||
if (iRet < 0 && !TC_Socket::isPending())
|
||||
{
|
||||
TLOGTARS("[tcp send," << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString()
|
||||
<< ",fail! errno:" << TC_Exception::getSystemCode() << ","
|
||||
<< TC_Exception::parseError(TC_Exception::getSystemCode()) << ",close]" << endl);
|
||||
|
||||
close();
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
if(iRet < 0 && TC_Socket::isPending())
|
||||
{
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->modFd(_fd, &_fdInfo, EPOLLIN | EPOLLOUT);
|
||||
}
|
||||
#endif
|
||||
TLOGTARS("[tcp send," << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ","
|
||||
<< _ep.getConnectEndpoint()->toString() << ",len:" << iRet <<"]" << endl);
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
int TcpTransceiver::recv(void* buf, uint32_t len, uint32_t flag)
|
||||
{
|
||||
//只有是连接状态才能收发数据
|
||||
if(eConnected != _connStatus)
|
||||
return -1;
|
||||
|
||||
int iRet = ::recv(_fd, (char*)buf, len, flag);
|
||||
|
||||
if (iRet == 0 || (iRet < 0 && !TC_Socket::isPending()))
|
||||
{
|
||||
TLOGTARS("[tcp recv, " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << ", " << _ep.getConnectEndpoint()->toString() <<",ret " << iRet
|
||||
<< ", fail! errno:" << TC_Exception::getSystemCode() << "," << TC_Exception::parseError(TC_Exception::getSystemCode()) << ",close]" << endl);
|
||||
|
||||
close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
if(iRet < 0 && TC_Socket::isPending())
|
||||
{
|
||||
_adapterProxy->getObjProxy()->getCommunicatorEpoll()->modFd(_fd, &_fdInfo, EPOLLIN | EPOLLOUT);
|
||||
}
|
||||
#endif
|
||||
TLOGTARS("[tcp recv," << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString() << ",ret:" << iRet << "]" << endl);
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
UdpTransceiver::UdpTransceiver(AdapterProxy * pAdapterProxy, const EndpointInfo &ep)
|
||||
: Transceiver(pAdapterProxy, ep)
|
||||
,_pRecvBuffer(NULL)
|
||||
{
|
||||
// UDP不支持鉴权
|
||||
_authState = AUTH_SUCC;
|
||||
|
||||
if(!_pRecvBuffer)
|
||||
{
|
||||
_pRecvBuffer = new char[DEFAULT_RECV_BUFFERSIZE];
|
||||
if(!_pRecvBuffer)
|
||||
{
|
||||
throw TC_Exception("obj: '" + _adapterProxy->getObjProxy()->name() + "' malloc udp receive buffer fail");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UdpTransceiver::~UdpTransceiver()
|
||||
{
|
||||
if(_pRecvBuffer)
|
||||
{
|
||||
delete _pRecvBuffer;
|
||||
_pRecvBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int UdpTransceiver::doResponse()
|
||||
{
|
||||
if(!isValid()) return -1;
|
||||
|
||||
int recv = 0;
|
||||
|
||||
// done.clear();
|
||||
do
|
||||
{
|
||||
if ((recv = this->recv(_pRecvBuffer, DEFAULT_RECV_BUFFERSIZE, 0)) > 0)
|
||||
{
|
||||
TLOGTARS("[udp doResponse, " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << ",recvbuf:" << recv << "]" << endl);
|
||||
|
||||
_recvBuffer.clearBuffers();
|
||||
_recvBuffer.addBuffer(_pRecvBuffer, recv);
|
||||
|
||||
try
|
||||
{
|
||||
shared_ptr<ResponsePacket> rsp = std::make_shared<ResponsePacket>();
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE ret;
|
||||
|
||||
ret = _adapterProxy->getObjProxy()->getProxyProtocol().responseFunc(_recvBuffer, *rsp.get());
|
||||
|
||||
if(ret == TC_NetWorkBuffer::PACKET_ERR || ret == TC_NetWorkBuffer::PACKET_LESS)
|
||||
{
|
||||
TLOGERROR("[udp doResponse," << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString() << ",tcp recv decode error, ret:" << ret << endl);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
finishInvoke(rsp);
|
||||
}
|
||||
}
|
||||
catch (exception &ex)
|
||||
{
|
||||
TLOGERROR("[udp doResponse, " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString()
|
||||
<< ", udp recv decode error:" << ex.what() << endl);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
TLOGERROR("[udp doResponse, " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString()
|
||||
<< ", udp recv decode error." << endl);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (recv > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UdpTransceiver::send(const void* buf, uint32_t len, uint32_t flag)
|
||||
{
|
||||
if(!isValid()) return -1;
|
||||
|
||||
socklen_t addrlen = _ep.isIPv6() ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||
int iRet=::sendto(_fd, (const char*)buf, len, flag, _ep.connectAddrPtr(), addrlen);
|
||||
|
||||
if (iRet<0)
|
||||
{
|
||||
if(!TC_Socket::isPending())
|
||||
{
|
||||
TLOGERROR("[udp send " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString() << ", fail! errno:"
|
||||
<< TC_Exception::getSystemCode() << ","
|
||||
<< TC_Exception::parseError(TC_Exception::getSystemCode()) << ",close]" << endl);
|
||||
|
||||
close();
|
||||
|
||||
return iRet;
|
||||
}
|
||||
iRet=0;
|
||||
}
|
||||
else if(iRet>0 && iRet != (int)len)
|
||||
{
|
||||
TLOGERROR("[udp send, " << _adapterProxy->getObjProxy()->name()
|
||||
<< ",fd:" << _fd << "," << _ep.getConnectEndpoint()->toString() << ", send error."
|
||||
<< ", len:" << len << ", sendLen:" << iRet << endl);
|
||||
//udp只发一次 发送一半也算全部发送成功
|
||||
iRet = len;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
int UdpTransceiver::recv(void* buf, uint32_t len, uint32_t flag)
|
||||
{
|
||||
if(!isValid()) return -1;
|
||||
|
||||
int iRet = ::recvfrom(_fd, (char*)buf, len, flag, NULL, NULL); //need check from_ip & port
|
||||
|
||||
if (iRet < 0 && !TC_Socket::isPending())
|
||||
{
|
||||
TLOGERROR("[udp recv " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ","
|
||||
<< _ep.getConnectEndpoint()->toString() << ", fail! errno:" << TC_Exception::getSystemCode() << ","
|
||||
<< TC_Exception::parseError(TC_Exception::getSystemCode()) << ",close]" << endl);
|
||||
|
||||
close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
}
|
|
@ -42,14 +42,14 @@ MYSQL_LIB_DIR += -L/usr/local/mysql/lib/mysql -L/usr/local/mysql/lib -L/usr/li
|
|||
LIB_DIR += ${MYSQL_LIB_DIR}
|
||||
INC_DIR += ${MYSQL_INC}
|
||||
|
||||
ifneq ($(TARS_OPENTRACKING), 0)
|
||||
ifneq ($(TARS_OPENTRACKING), )
|
||||
OPENTRACKING_INC += -I/usr/local/include
|
||||
OPENTRACKING_LIB_DIR += -L/usr/local/lib
|
||||
LIB_DIR += ${OPENTRACKING_LIB_DIR}
|
||||
INC_DIR += ${OPENTRACKING_INC}
|
||||
endif
|
||||
endif
|
||||
// ifneq ($(TARS_OPENTRACKING), 0)
|
||||
// ifneq ($(TARS_OPENTRACKING), )
|
||||
// OPENTRACKING_INC += -I/usr/local/include
|
||||
// OPENTRACKING_LIB_DIR += -L/usr/local/lib
|
||||
// LIB_DIR += ${OPENTRACKING_LIB_DIR}
|
||||
// INC_DIR += ${OPENTRACKING_INC}
|
||||
// endif
|
||||
// endif
|
||||
|
||||
|
||||
|
||||
|
@ -72,13 +72,13 @@ ifneq ($(TARS_HTTP2), )
|
|||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(TARS_OPENTRACKING), 0)
|
||||
ifneq ($(TARS_OPENTRACKING), )
|
||||
#业务编译
|
||||
CFLAGS += -D_USE_OPENTRACKING=1
|
||||
LIB += -lopentracing -lzipkin_opentracing -lzipkin -lcurl
|
||||
endif
|
||||
endif
|
||||
// ifneq ($(TARS_OPENTRACKING), 0)
|
||||
// ifneq ($(TARS_OPENTRACKING), )
|
||||
// #业务编译
|
||||
// CFLAGS += -D_USE_OPENTRACKING=1
|
||||
// LIB += -lopentracing -lzipkin_opentracing -lzipkin -lcurl
|
||||
// endif
|
||||
// endif
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -95,14 +95,14 @@ FILE(WRITE ${TARS_UPLOAD_TARS} "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ech
|
|||
|
||||
####################################################################
|
||||
|
||||
# k8s taf
|
||||
# k8s
|
||||
set(TARS_K8S_WEB_HOST "" CACHE STRING "set k8s web host")
|
||||
IF (TARS_K8S_WEB_HOST STREQUAL "")
|
||||
set(TARS_K8S_WEB_HOST "http://taf.test.whup.com:8080")
|
||||
set(TARS_K8S_WEB_HOST "http://tars.test.whup.com:8080")
|
||||
ENDIF ()
|
||||
|
||||
set(TARS_K8S_TOKEN "" CACHE STRING "set k8s web token")
|
||||
set(TARS_K8S_BASE_IMAGE "" CACHE STRING "set taf k8s base image")
|
||||
set(TARS_K8S_BASE_IMAGE "" CACHE STRING "set tars k8s base image")
|
||||
set(TARS_K8S_UPLOAD "${CMAKE_BINARY_DIR}/run-k8s-upload.cmake")
|
||||
FILE(WRITE ${TARS_K8S_UPLOAD} "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo upload k8s all)\n")
|
||||
FILE(WRITE ${TARS_K8S_UPLOAD_TARS} "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E echo upload k8s tars all)\n")
|
||||
|
|
|
@ -19,18 +19,21 @@
|
|||
|
||||
#include "util/tc_timeout_queue_new.h"
|
||||
#include "util/tc_timeout_queue_map.h"
|
||||
#include "util/tc_transceiver.h"
|
||||
#include "servant/Global.h"
|
||||
#include "servant/EndpointInfo.h"
|
||||
#include "servant/ObjectProxy.h"
|
||||
#include "servant/Transceiver.h"
|
||||
#include "servant/Message.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/AuthLogic.h"
|
||||
#include "servant/AuthF.h"
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
#include <opentracing/span.h>
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// #include <opentracing/span.h>
|
||||
// #endif
|
||||
namespace tars
|
||||
{
|
||||
/**
|
||||
|
@ -69,7 +72,7 @@ public:
|
|||
* @param req
|
||||
* @return
|
||||
*/
|
||||
void doInvoke(bool initInvoke);
|
||||
void doInvoke();
|
||||
|
||||
/**
|
||||
* server端的响应包返回
|
||||
|
@ -83,6 +86,12 @@ public:
|
|||
*/
|
||||
bool checkActive(bool connecting);
|
||||
|
||||
/**
|
||||
* 重置try time
|
||||
* @param next: true: 设置为下一次重试时间, 这之前不能发起连接, false: 设置为当前时间(马上就可以发起连接)
|
||||
*/
|
||||
void resetRetryTime(bool next = true);
|
||||
|
||||
/**
|
||||
* 记录连接是否异常
|
||||
*/
|
||||
|
@ -97,19 +106,15 @@ public:
|
|||
* 处理stat
|
||||
*/
|
||||
void mergeStat(map<StatMicMsgHead, StatMicMsgBody> & mStatMicMsg);
|
||||
/**
|
||||
* 处理采样
|
||||
*/
|
||||
// void sample(ReqMessage * msg);
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
/**
|
||||
* Zipkin调用链
|
||||
*/
|
||||
void startTrack(ReqMessage * msg);
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// /**
|
||||
// * Zipkin调用链
|
||||
// */
|
||||
// void startTrack(ReqMessage * msg);
|
||||
|
||||
void finishTrack(ReqMessage * msg);
|
||||
#endif
|
||||
// void finishTrack(ReqMessage * msg);
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* 获取ObjectProxy
|
||||
|
@ -120,7 +125,7 @@ public:
|
|||
* 获取端口信息
|
||||
* @return const EndpointInfo&
|
||||
*/
|
||||
inline const EndpointInfo & endpoint() const { return _trans->getEndpointInfo(); }
|
||||
inline const EndpointInfo & endpoint() const { return _ep; }
|
||||
|
||||
/**
|
||||
* 连接超时的时间
|
||||
|
@ -130,7 +135,7 @@ public:
|
|||
/**
|
||||
* 连接是否超时
|
||||
*/
|
||||
inline bool isConnTimeout() { return _connTimeout; }
|
||||
inline bool isConnTimeout() { return _trans->isConnTimeout(); }
|
||||
|
||||
/**
|
||||
* 设置连接是否超时
|
||||
|
@ -160,9 +165,9 @@ public:
|
|||
/**
|
||||
* 获取连接
|
||||
*
|
||||
* @return Transceiver*
|
||||
* @return TC_Transceiver*
|
||||
*/
|
||||
inline Transceiver* trans() { return _trans.get(); }
|
||||
inline TC_Transceiver* trans() { return _trans.get(); }
|
||||
|
||||
/**
|
||||
* 设置节点的静态权重值
|
||||
|
@ -178,7 +183,6 @@ public:
|
|||
* 获取节点的静态权重值
|
||||
*/
|
||||
inline int getWeight() { return _staticWeight; }
|
||||
|
||||
/**
|
||||
* 将权重变化标识重置为false
|
||||
*/
|
||||
|
@ -200,28 +204,49 @@ public:
|
|||
*/
|
||||
inline int getId() const { return _id; }
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
inline Transceiver* getTransceiver() const { return _trans.get(); }
|
||||
|
||||
/**
|
||||
* 屏蔽结点
|
||||
*/
|
||||
void onSetInactive();
|
||||
|
||||
/**
|
||||
* get timeout queue
|
||||
* @return
|
||||
*/
|
||||
TC_TimeoutQueueNew<ReqMessage*> * getTimeoutQueue() { return _timeoutQueue.get(); }
|
||||
|
||||
protected:
|
||||
|
||||
//创建完网络句柄后的回调
|
||||
shared_ptr<TC_ProxyInfo> onCreateCallback(TC_Transceiver*);
|
||||
|
||||
std::shared_ptr<TC_OpenSSL> onOpensslCallback(TC_Transceiver*);
|
||||
|
||||
void onCloseCallback(TC_Transceiver*, TC_Transceiver::CloseReason reason, const string &err);
|
||||
|
||||
void onConnectCallback(TC_Transceiver*);
|
||||
|
||||
void onRequestCallback(TC_Transceiver*);
|
||||
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> onSendAuthCallback(TC_Transceiver*);
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE onVerifyAuthCallback(TC_NetWorkBuffer &, TC_Transceiver*);
|
||||
|
||||
TC_NetWorkBuffer::PACKET_TYPE onParserCallback(TC_NetWorkBuffer&, TC_Transceiver*);
|
||||
|
||||
void onCompletePackage(TC_Transceiver*);
|
||||
|
||||
void doInvoke_serial();
|
||||
|
||||
TC_TimeoutQueueNew<ReqMessage*> * getTimeoutQueue() { return _timeoutQueue.get(); }
|
||||
private:
|
||||
|
||||
|
||||
/**
|
||||
* 屏蔽结点
|
||||
*/
|
||||
void setInactive();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* 请求的响应处理
|
||||
|
@ -305,10 +330,15 @@ private:
|
|||
*/
|
||||
ReqMessage* _requestMsg = NULL;
|
||||
|
||||
/**
|
||||
* ep
|
||||
*/
|
||||
EndpointInfo _ep;
|
||||
|
||||
/*
|
||||
* 收发包处理
|
||||
*/
|
||||
std::unique_ptr<Transceiver> _trans;
|
||||
std::unique_ptr<TC_Transceiver> _trans;
|
||||
|
||||
/*
|
||||
* 超时队列
|
||||
|
@ -355,10 +385,6 @@ private:
|
|||
*/
|
||||
time_t _nextRetryTime;
|
||||
|
||||
/*
|
||||
* 是否连接超时
|
||||
*/
|
||||
bool _connTimeout;
|
||||
|
||||
/*
|
||||
* 是否连接异常
|
||||
|
@ -374,6 +400,7 @@ private:
|
|||
* 静态权重值
|
||||
*/
|
||||
int _staticWeight;
|
||||
|
||||
/*
|
||||
* 静态权重是否变更过
|
||||
*/
|
||||
|
@ -397,14 +424,14 @@ private:
|
|||
/*
|
||||
* 模块间调用统计信息的body信息
|
||||
*/
|
||||
map<string,StatMicMsgBody> _statBody;
|
||||
unordered_map<string,StatMicMsgBody> _statBody;
|
||||
|
||||
/*
|
||||
* 调用链信息
|
||||
*/
|
||||
#ifdef TARS_OPENTRACKING
|
||||
map<int,std::unique_ptr<opentracing::Span>> _spanMap;
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// map<int,std::unique_ptr<opentracing::Span>> _spanMap;
|
||||
// #endif
|
||||
int _id;
|
||||
static atomic<int> _idGen;
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ using namespace tup;
|
|||
namespace tars
|
||||
{
|
||||
|
||||
class Transceiver;
|
||||
class TC_Transceiver;
|
||||
|
||||
#define TARS_NET_MIN_PACKAGE_SIZE 5
|
||||
#define TARS_NET_MAX_PACKAGE_SIZE 1024*1024*10
|
||||
|
@ -50,7 +50,7 @@ T net2host(T len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
class Transceiver;
|
||||
class TC_Transceiver;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -125,7 +125,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
typedef std::function<vector<char>(RequestPacket&, Transceiver *)> request_protocol;
|
||||
//typedef std::function<vector<char>(RequestPacket&, TC_Transceiver *)> request_protocol;
|
||||
|
||||
typedef std::function<shared_ptr<TC_NetWorkBuffer::Buffer>(RequestPacket&, TC_Transceiver*)> request_protocol;
|
||||
|
||||
typedef std::function<TC_NetWorkBuffer::PACKET_TYPE(TC_NetWorkBuffer&, ResponsePacket&)> response_protocol;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -140,21 +143,24 @@ public:
|
|||
*/
|
||||
ProxyProtocol() : requestFunc(streamRequest) {}
|
||||
|
||||
static vector<char> http1Request(tars::RequestPacket& request, Transceiver *);
|
||||
/**
|
||||
* 将TarsOutputStream<BufferWriter>换成shared_ptr<TC_NetWorkBuffer::Buffer>, 且中间没有内存copy
|
||||
* 注意: 转换后os无效了, 数据被置换到shared_ptr<TC_NetWorkBuffer::Buffer>
|
||||
*/
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> toBuffer(TarsOutputStream<BufferWriter> &os);
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> http1Request(tars::RequestPacket& request, TC_Transceiver *);
|
||||
static TC_NetWorkBuffer::PACKET_TYPE http1Response(TC_NetWorkBuffer &in, ResponsePacket& done);
|
||||
|
||||
// static vector<char> httpJceRequest(taf::RequestPacket& request, Transceiver *);
|
||||
// static TC_NetWorkBuffer::PACKET_TYPE httpJceResponse(TC_NetWorkBuffer &in, ResponsePacket& done);
|
||||
#if TARS_HTTP2
|
||||
|
||||
// ENCODE function, called by network thread
|
||||
static vector<char> http2Request(tars::RequestPacket& request, Transceiver *);
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> http2Request(tars::RequestPacket& request, TC_Transceiver *);
|
||||
|
||||
// DECODE function, called by network thread
|
||||
static TC_NetWorkBuffer::PACKET_TYPE http2Response(TC_NetWorkBuffer &in, ResponsePacket& done);
|
||||
|
||||
// ENCODE function, called by network thread
|
||||
static vector<char> grpcRequest(tars::RequestPacket& request, Transceiver *);
|
||||
// ENCODE function, called by network thread
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> grpcRequest(tars::RequestPacket& request, TC_Transceiver *);
|
||||
|
||||
// DECODE function, called by network thread
|
||||
static TC_NetWorkBuffer::PACKET_TYPE grpcResponse(TC_NetWorkBuffer &in, ResponsePacket& done);
|
||||
|
@ -165,13 +171,15 @@ public:
|
|||
* @param request
|
||||
* @param buff
|
||||
*/
|
||||
static vector<char> streamRequest(RequestPacket& request, Transceiver *)
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> streamRequest(RequestPacket& request, TC_Transceiver *)
|
||||
{
|
||||
return request.sBuffer;
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
buff->addBuffer(request.sBuffer);
|
||||
return buff;
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通二进制包普taf请求包
|
||||
* 普通二进制包普tars请求包
|
||||
* @param request
|
||||
* @param buff
|
||||
*/
|
||||
|
@ -465,7 +473,7 @@ public:
|
|||
* @param request
|
||||
* @param buff
|
||||
*/
|
||||
static vector<char> tarsRequest(RequestPacket& request, Transceiver *);
|
||||
static shared_ptr<TC_NetWorkBuffer::Buffer> tarsRequest(RequestPacket& request, TC_Transceiver *);
|
||||
|
||||
/**
|
||||
* tars响应包解析
|
||||
|
@ -539,8 +547,8 @@ public:
|
|||
else
|
||||
{
|
||||
vector<char> buffer;
|
||||
bool ret = in.parseBufferOf4(buffer, iMinLength, iMaxLength);
|
||||
if(!ret)
|
||||
auto ret = in.parseBufferOf4(buffer, iMinLength, iMaxLength);
|
||||
if (ret == TC_NetWorkBuffer::PACKET_LESS)
|
||||
{
|
||||
throw TarsDecodeException("parse buffer exception");
|
||||
}
|
||||
|
@ -653,6 +661,7 @@ public:
|
|||
|
||||
if (rsp.iVersion == TUPVERSION)
|
||||
{
|
||||
//buffer包括4个字节长度
|
||||
vector<char> buffer;
|
||||
buffer.resize(iHeaderLen);
|
||||
|
||||
|
@ -714,12 +723,11 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
request_protocol requestFunc;
|
||||
request_protocol requestFunc;
|
||||
|
||||
response_protocol responseFunc;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,18 +30,19 @@
|
|||
#include "servant/ServantHelper.h"
|
||||
#include "servant/ServantHandle.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/CommunicatorFactory.h"
|
||||
#include "Communicator.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#include "servant/RemoteConfig.h"
|
||||
#include "servant/RemoteNotify.h"
|
||||
#include "servant/NotifyObserver.h"
|
||||
#include "util/tc_openssl.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
#define OUT_LINE (TC_Common::outfill("", '-', 80))
|
||||
#define OUT_LINE_LONG (TC_Common::outfill("", '=', 80))
|
||||
#define OUT_LINE_TAB(x) (TC_Common::outfill("", '-', 80 - 4*x))
|
||||
#define OUT_LINE (TC_Common::outfill("", '-', 100))
|
||||
#define OUT_LINE_LONG (TC_Common::outfill("", '=', 100))
|
||||
#define OUT_LINE_TAB(x) (TC_Common::outfill("", '-', 100 - 4*x))
|
||||
|
||||
/**
|
||||
* 以下定义配置框架支持的命令
|
||||
|
@ -122,14 +123,13 @@ struct SVT_DLL_API ServerConfig
|
|||
static std::string Notify; //信息通知中心
|
||||
static std::string ConfigFile; //框架配置文件路径
|
||||
static bool CloseCout;
|
||||
static int ReportFlow; //是否服务端上报所有接口stat流量 0不上报 1上报(用于非taf协议服务流量统计)
|
||||
static int ReportFlow; //是否服务端上报所有接口stat流量 0不上报 1上报(用于非tars协议服务流量统计)
|
||||
static int IsCheckSet; //是否对按照set规则调用进行合法性检查 0,不检查,1检查
|
||||
static bool OpenCoroutine; //是否启用协程处理方式
|
||||
static int OpenCoroutine; //是否启用协程处理方式(0~3)
|
||||
static size_t CoroutineMemSize; //协程占用内存空间的最大大小
|
||||
static uint32_t CoroutineStackSize; //每个协程的栈大小(默认128k)
|
||||
static int NetThread; //servernet thread
|
||||
static bool ManualListen; //是否启用手工端口监听
|
||||
static bool MergeNetImp; //网络线程和IMP线程合并(以网络线程个数为准)
|
||||
static int BackPacketLimit; //回包积压检查
|
||||
static int BackPacketMin; //回包速度检查
|
||||
|
||||
|
@ -143,7 +143,6 @@ struct SVT_DLL_API ServerConfig
|
|||
};
|
||||
|
||||
class PropertyReport;
|
||||
class NotifyObserver;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -163,11 +162,21 @@ public:
|
|||
virtual ~Application();
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* 初始化 --config=xxxx
|
||||
* @param argv
|
||||
*/
|
||||
void main(int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* init
|
||||
* @param option
|
||||
*/
|
||||
void main(const TC_Option &option);
|
||||
|
||||
/**
|
||||
* config , 实际配置文件的内容(而不是目录)
|
||||
* @param config
|
||||
*/
|
||||
void main(const string &config);
|
||||
|
||||
/**
|
||||
|
@ -175,6 +184,11 @@ public:
|
|||
*/
|
||||
void waitForShutdown();
|
||||
|
||||
/**
|
||||
* 等待服务已经正常运行了
|
||||
*/
|
||||
void waitForReady();
|
||||
|
||||
public:
|
||||
/**
|
||||
* 获取配置文件
|
||||
|
@ -191,11 +205,11 @@ public:
|
|||
*/
|
||||
static CommunicatorPtr& getCommunicator();
|
||||
|
||||
/**
|
||||
* 获取服务Server对象
|
||||
*
|
||||
* @return TC_EpollServerPtr&
|
||||
*/
|
||||
/**
|
||||
* 获取服务Server对象
|
||||
*
|
||||
* @return TC_EpollServerPtr&
|
||||
*/
|
||||
TC_EpollServerPtr &getEpollServer() { return _epollServer; }
|
||||
const TC_EpollServerPtr &getEpollServer() const { return _epollServer; }
|
||||
|
||||
|
@ -205,7 +219,7 @@ public:
|
|||
void terminate();
|
||||
|
||||
/**
|
||||
* 获取tarsservant框架的版本
|
||||
* 获取框架的版本
|
||||
*/
|
||||
static string getTarsVersion();
|
||||
|
||||
|
@ -237,13 +251,12 @@ public:
|
|||
_servantHelper->addServant<T>(id, this, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加Servant
|
||||
* @param T
|
||||
* @param id
|
||||
* @param p, params for handle
|
||||
*/
|
||||
/**
|
||||
* 添加Servant
|
||||
* @param T
|
||||
* @param id
|
||||
* @param p, p will pass to T, T must has constructor with p
|
||||
*/
|
||||
template<typename T, typename P>
|
||||
void addServantWithParams(const string &id, const P &p)
|
||||
{
|
||||
|
@ -260,10 +273,10 @@ public:
|
|||
* get notify observer
|
||||
* @return
|
||||
*/
|
||||
const shared_ptr<NotifyObserver> &getNotifyObserver() { return _notifyObserver; }
|
||||
shared_ptr<NotifyObserver> &getNotifyObserver() { return _notifyObserver; }
|
||||
|
||||
/**
|
||||
* 非taf协议server,设置Servant的协议解析器
|
||||
* 非tars协议server,设置Servant的协议解析器
|
||||
* @param protocol
|
||||
* @param servant
|
||||
*/
|
||||
|
@ -285,7 +298,7 @@ protected:
|
|||
/**
|
||||
* 析够, 进程只会调用一次
|
||||
*/
|
||||
virtual void destroyApp() = 0;
|
||||
virtual void destroyApp() {};
|
||||
|
||||
/**
|
||||
* 解析服务的网络配置(业务可以在里面变更网络配置)
|
||||
|
@ -439,16 +452,16 @@ protected:
|
|||
*/
|
||||
void onAccept(TC_EpollServer::Connection* cPtr);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param command
|
||||
* @param params
|
||||
* @param result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
void addServantOnClose(const string& servant, const TC_EpollServer::close_functor& f);
|
||||
// /**
|
||||
// *
|
||||
// *
|
||||
// * @param command
|
||||
// * @param params
|
||||
// * @param result
|
||||
// *
|
||||
// * @return bool
|
||||
// */
|
||||
// void addServantOnClose(const string& servant, const TC_EpollServer::close_functor& f);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -488,11 +501,11 @@ protected:
|
|||
/**
|
||||
* 解析配置文件
|
||||
*/
|
||||
void parseConfig(const string &config);
|
||||
void parseConfig(const string &config);
|
||||
|
||||
/**
|
||||
* 解析ip权限allow deny 次序
|
||||
*/
|
||||
/**
|
||||
* 解析ip权限allow deny 次序
|
||||
*/
|
||||
TC_EpollServer::BindAdapter::EOrder parseOrder(const string &s);
|
||||
|
||||
/**
|
||||
|
@ -549,20 +562,23 @@ protected:
|
|||
*/
|
||||
std::vector<TC_EpollServer::accept_callback_functor> _acceptFuncs;
|
||||
|
||||
/**
|
||||
* servant helper
|
||||
*/
|
||||
shared_ptr<ServantHelperManager> _servantHelper;
|
||||
/**
|
||||
* servant helper
|
||||
*/
|
||||
shared_ptr<ServantHelperManager> _servantHelper;
|
||||
|
||||
/**
|
||||
* notify observer
|
||||
*/
|
||||
shared_ptr<NotifyObserver> _notifyObserver;
|
||||
/**
|
||||
* notify observer
|
||||
*/
|
||||
shared_ptr<NotifyObserver> _notifyObserver;
|
||||
|
||||
/**
|
||||
* ssl ctx
|
||||
*/
|
||||
shared_ptr<TC_OpenSSL::CTX> _ctx = nullptr;
|
||||
shared_ptr<TC_OpenSSL::CTX> _ctx = nullptr;
|
||||
|
||||
size_t _ctrlCId = -1;
|
||||
size_t _termId = -1;
|
||||
|
||||
PropertyReport * _pReportQueue;
|
||||
PropertyReport * _pReportConRate;
|
||||
|
|
|
@ -3,28 +3,15 @@
|
|||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
/**
|
||||
* server :默认鉴权逻辑
|
||||
* server:默认生成鉴权请求方法
|
||||
*/
|
||||
bool processAuth(TC_EpollServer::Connection *c, const shared_ptr<TC_EpollServer::RecvContext>& data, const string &objName);
|
||||
|
||||
/**
|
||||
* server :默认鉴权逻辑
|
||||
*/
|
||||
int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info);
|
||||
|
||||
/**
|
||||
* server :默认鉴权方法
|
||||
*/
|
||||
//int defaultProcessAuthReq(const char* request, size_t len, const string& expectObj);
|
||||
//int defaultProcessAuthReq(const string& request, const string& expectObj);
|
||||
int defaultProcessAuthReq(const char* request, size_t len, const TC_EpollServer::BindAdapterPtr &adapter, const string &objName);
|
||||
pair<TC_NetWorkBuffer::PACKET_TYPE, shared_ptr<TC_NetWorkBuffer::Buffer>> serverVerifyAuthCallback(TC_NetWorkBuffer &, TC_Transceiver*, weak_ptr<TC_EpollServer::BindAdapter> adapter, const string &expectObj);
|
||||
|
||||
/**
|
||||
* client:默认生成鉴权请求方法
|
||||
*/
|
||||
string defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMethod = "sha1" */ );
|
||||
vector<char> defaultCreateAuthReq(const BasicAuthInfo& info);
|
||||
|
||||
} // end namespace tars
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "servant/Global.h"
|
||||
#include "util/tc_thread_queue.h"
|
||||
#include "util/tc_thread_mutex.h"
|
||||
#include <functional>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
namespace tars
|
||||
{
|
||||
class NotifyObserver;
|
||||
|
@ -84,9 +84,9 @@ protected:
|
|||
*/
|
||||
map<string, TAdminFunc> _procFunctors;
|
||||
|
||||
/**
|
||||
* notify observer
|
||||
*/
|
||||
/**
|
||||
* notify observer
|
||||
*/
|
||||
shared_ptr<NotifyObserver> _observer;
|
||||
|
||||
};
|
||||
|
|
|
@ -23,23 +23,99 @@
|
|||
#include "servant/Global.h"
|
||||
#include "servant/ServantProxy.h"
|
||||
#include "servant/ServantProxyFactory.h"
|
||||
#include "servant/ObjectProxyFactory.h"
|
||||
//#include "servant/ObjectProxyFactory.h"
|
||||
#include "servant/AsyncProcThread.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
// #include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/RemoteLogger.h"
|
||||
#ifdef TARS_OPENTRACKING
|
||||
#include "zipkin/opentracing.h"
|
||||
#include "zipkin/tracer.h"
|
||||
#include "zipkin/ip_address.h"
|
||||
#endif
|
||||
|
||||
#define CONFIG_ROOT_PATH "/tars/application/client"
|
||||
//
|
||||
//struct ssl_ctx_st;
|
||||
//typedef struct ssl_ctx_st SSL_CTX;
|
||||
#include "util/tc_openssl.h"
|
||||
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// #include "zipkin/opentracing.h"
|
||||
// #include "zipkin/tracer.h"
|
||||
// #include "zipkin/ip_address.h"
|
||||
// #endif
|
||||
//
|
||||
const static string CONFIG_ROOT_PATH = string("/tars/application/client");
|
||||
|
||||
/**
|
||||
* 设计核心:
|
||||
* - 设计的核心是协程化, 如果本身就处于协程状态下, rpc网络通信就复现当前的协程调度器, 从而网络收发逻辑和rpc都在一个线程中处理, 减少线程切换, 降低延时!!!
|
||||
* - 如果发起rpc的线程不是协程, 则请求丢给了实际的网络线程处理, 和之前版本保持一致
|
||||
* - 结合到服务器端的模型, 这样设计的好处是, 如果都处于协程模式, 客户端和服务器可以复用相同的协程调度器, 从而保证服务器接受请求, 发起rpc, 接收rpc响应, 到回包给客户端, 都在一个线程中处理, 无线程切换逻辑!
|
||||
* - 从而大幅度降低了系统延时!
|
||||
*
|
||||
* 基本说明:
|
||||
* - 通信器Communicator是包含了所有客户端调用的资源, 原则上在调用生命周期都必须存在
|
||||
* - 每个通信器都包含多个CommunicatorEpoll, 这个是Communicator创建是构建出来的, 此时CommunicatorEpoll的个数和客户端网络线程相同, 至少有1个
|
||||
* - 把这种初始就生成的CommunicatorEpoll作为公有的, 后续可能会动态创建私有的CommunicatorEpoll
|
||||
* - 无论公有还是私有CommunicatorEpoll, 网络层都用的协程调度器中的epoller对象, 这样方便复用(尤其是针对私有CommunicatorEpoll)
|
||||
* - 私有CommunicatorEpoll并不是完整的网路线程, 它复用了业务线程中的协程调度器(这里业务线程可能是服务器端的业务线程/协程, 自带了协程调度器), 参见后续说明
|
||||
* - 公有和私有的CommunicatorEpoll都会存在于Communicator对象中
|
||||
* - 无论是公有还是私有的CommunicatorEpoll的生命周期由通信器来管理, 通信器析构时会被释放
|
||||
* - 一旦Communicator被释放, 它包含的所有资源都被释放了, 由它创建的ServantPrx, 都不能再进行网络通信!!!
|
||||
* - ServantProxy针对每个通信器而言, 是全局唯一的, 根据stringToProxy传入的obj来唯一确定
|
||||
* - 调用Communicator::stringToProxy, 构建ServantProxy时, 会调用每个CommunicatorEpoll创建对应的ObjectProxy
|
||||
* - 即每个ObjectProxy实例唯一对应了一个CommunicatorEpoll, 即代表了网络收发处理线程
|
||||
* - ObjectProxy的生命周期被CommunicatorEpoll管理, 当CommunicatorEpoll释放时, ObjectProxy会被释放
|
||||
* - 实际的rpc调用, 虽然调用的是ServantProxy, 但是实际会选择具体发送的ObjectProxy(即选择了CommunicatorEpoll) 和 发送队列
|
||||
* - 这个发送队列即: 在业务线程 和 CommunicatorEpoll 存在一个无锁的队列(限制长度, 每个元素是ReqMessage, 代表本次请求)
|
||||
* - 这个无锁队列, 被业务线程的私有数据管理, 当第一次使用某个CommunicatorEpoll时, 创建出来, 它的析构是复杂逻辑, 参考后续逻辑!
|
||||
* - 业务线程退出时, 会导致线程私有数据析构, 析构时发消息给CommunicatorEpoll, 在网络线程中释放资源
|
||||
* - 所以框架要求, 业务线程先释放, 才能释放框架的网路线程
|
||||
*
|
||||
* CommunicatorEpoll设计说明
|
||||
* 1 当业务线程处于协程中, 只使用私有CommunicatorEpoll(不使用的公用的)
|
||||
* - 基于当前协程的调度器TC_CoroutineScheduler, 全新创建CommunicatorEpoll
|
||||
* - 使用该CommunicatorEpoll来处理网络请求, 这样复用相同的调度器(该调度器可能是服务端线程)
|
||||
* - 这样所有网络请求都在同一个线程里面处理了
|
||||
* - 该调度器, 保存在线程私有对象中(和Communicator指针关联), 同时也保存在Communicator中
|
||||
* - 当Communicator对象析构时, 主动释放该CommunicatorEpoll
|
||||
* - 创建CommunicatorEpoll时, 注意需要clone所有的ObjectProxy(从公有CommunicatorEpoll中复制), 并选择返回对应的ObjectProxy
|
||||
* - 使用ObjectProxy来发送数据
|
||||
* - 这种场景下, 数据收发其实都在业务线程中处理了!!!
|
||||
* 2 当业务线程处于普通线程中(不存在协程调度器), 只使用公有CommunicatorEpoll
|
||||
* - 轮询选择公有的CommunicatorEpoll的, 注意此时不选择私有CommunicatorEpoll来发送数据, 降低系统的复杂度
|
||||
* - 轮询的计数器保持在线程私有数据中
|
||||
*
|
||||
* 析构问题处理
|
||||
* - 通信器是管理客户端资源的对象
|
||||
* - 通信器析构 以及 业务线程(发起到rpc调用)退出时, 如何处理相关资源释放的是重点需要考虑的
|
||||
* - 这里最核心的处理是 业务线程和CommunicatorEpoll之前有发送队列, 这个发送队列由业务线程私有数据保持, 它的问题在于:
|
||||
* 1 如果业务线程先退出, 将发送队列先析构, 但是如果此时网络线程仍在使用, 则会有问题
|
||||
* 2 如果网络线程先退出, 业务线程退出时, 拿到的CommunicatorEpoll指针可能有问题!
|
||||
* - 解决方案:
|
||||
* 1 CommunicatorEpoll使用shared_ptr, 业务线程私有数据中持有CommunicatorEpoll时, 采用weak_ptr, 这样业务线程退出时能感知CommunicatorEpoll是否还存在
|
||||
* 2 如果业务线程退出时, CommunicatorEpoll不存在了, 直接delete掉发送队列即可
|
||||
* 3 如果业务线程退出时, CommunicatorEpoll仍然存在, 发送通知给CommunicatorEpoll, 通知它业务线程退出
|
||||
* 4 发送队列使用shared_ptr被线程私有数据持有, 同时它作为weak_ptr被notify通知对象持有
|
||||
* 5 网络线程收到notify以后, 获取发送队列的weak_ptr, 转成shared_ptr以后才使用, 保证有效性, 如果转换后shared_ptr为NULL, 表示业务线程已经退出了, 此时可以不需要做任何处理
|
||||
* 6 如果notify对象释放时(CommunicatorEpoll析构), 会把发送队列中的数据清空, delete msg
|
||||
* 7 如果通信器先析构, 实际上会有一定的泄露(非常少), 线程私有变量中记录通信器信息的map不会删除记录(直到业务线程退出才会释放掉), 这里其实有资源泄露, 但是极少, 可以不管, 除非代码不断在构造和析构通信器!
|
||||
*
|
||||
* ObjectProxy创建的问题
|
||||
* - ServantProxy对象, 对每个服务而言, 是全局唯一的, 它背后对应的ObjectProxy, 是每个网络线程/协程都有一个, 即CommunicatorEpoll内部每个ServantProxy都对应了一个ObjectProxy
|
||||
* - 对于公有的CommunicatorEpoll, 它内部的ObjectProxy是stringToProxy时, 自动创建出来的
|
||||
* - 对于私有CommunicatorEpoll, 它内部的ObjectProxy是ServantProxy在invoke的时候创建出来的, 这样由于调用逻辑的原因, 私有CommunicatorEpoll内部拥有的ObjectProxy是不一样的!
|
||||
* - 私有CommunicatorEpoll内部ObjectProxy不一样, 导致了后需要更新ip list的机制不同
|
||||
*
|
||||
* ObjectProxy服务地址更新的问题
|
||||
* - 由于一个进程中CommunicatorEpoll可能会有多个(公有的+私有的), 从而会有多个ObjectProxy, 带来多次更新主控的问题
|
||||
* - 为了避免这种现象, 设计上目前只有公有CommunicatorEpoll且netThreadSeq==0的(isFirstNetThread), 才回主动更新主控
|
||||
* - 当第一个公有CommunicatorEpoll更新主控, 获取到服务的ip list之后, 会遍历所有CommunicatorEpoll, 通知所有CommunicatorEpoll里面对应的ObjectProxy去更新这个ip list
|
||||
* - 注意私有CommunicatorEpoll内部, 可能不存在这个ObjectProxy, 可能就不要更新ip list了, 需要特殊判断
|
||||
* - 私有CommunicatorEpoll中的ObjectProxy不会主动更新主控
|
||||
* -
|
||||
*/
|
||||
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class CommunicatorEpoll;
|
||||
class TC_OpenSSL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 客户端配置
|
||||
|
@ -131,24 +207,30 @@ public:
|
|||
proxy = (typename T::element_type *)(pServantProxy);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*获取客户端网络线程的个数
|
||||
/**
|
||||
* 获取公有网络线程个数
|
||||
* @return
|
||||
*/
|
||||
inline size_t getClientThreadNum()
|
||||
inline size_t getCommunicatorEpollNum()
|
||||
{
|
||||
return _clientThreadNum;
|
||||
return _communicatorEpoll.size();
|
||||
}
|
||||
|
||||
/*
|
||||
*获取客户端网络线程的对象
|
||||
/*
|
||||
*获取公有网络线程的对象
|
||||
*/
|
||||
inline CommunicatorEpoll * getCommunicatorEpoll(size_t iNum)
|
||||
inline const shared_ptr<CommunicatorEpoll> &getCommunicatorEpoll(size_t iNum)
|
||||
{
|
||||
assert(iNum<_clientThreadNum);
|
||||
assert(iNum < getCommunicatorEpollNum());
|
||||
return _communicatorEpoll[iNum];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的网络通信器(包括公有和私有的)
|
||||
* @return
|
||||
*/
|
||||
vector<shared_ptr<CommunicatorEpoll>> getAllCommunicatorEpoll();
|
||||
|
||||
/**
|
||||
* 获取属性
|
||||
* @param name
|
||||
|
@ -250,12 +332,10 @@ public:
|
|||
string getResourcesInfo();
|
||||
|
||||
/**
|
||||
* 更新prx的端口
|
||||
* @param prx
|
||||
* @param active
|
||||
* @param inactive
|
||||
* 是否析构中
|
||||
* @return bool
|
||||
*/
|
||||
void notifyUpdateEndpoints(const ServantPrx &prx, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive);
|
||||
bool isTerminating();
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -263,12 +343,6 @@ protected:
|
|||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
* 是否析构中
|
||||
* @return bool
|
||||
*/
|
||||
bool isTerminating();
|
||||
|
||||
/**
|
||||
* 获取对象代理生成器
|
||||
* @return ServantProxyFactoryPtr
|
||||
|
@ -302,6 +376,29 @@ protected:
|
|||
*/
|
||||
shared_ptr<TC_OpenSSL> newClientSSL(const string & objName);
|
||||
|
||||
/**
|
||||
* 通信器启动
|
||||
*/
|
||||
void notifyCommunicatorEpollStart();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param func
|
||||
*/
|
||||
void forEachSchedCommunicatorEpoll(std::function<void(const shared_ptr<CommunicatorEpoll> &)> func);
|
||||
|
||||
/**
|
||||
* 创建一个协程内的网络通信器
|
||||
* @return
|
||||
*/
|
||||
shared_ptr<CommunicatorEpoll> createSchedCommunicatorEpoll(size_t netThreadSeq, const shared_ptr<ReqInfoQueue> &reqInfoQueue);
|
||||
|
||||
/**
|
||||
* 删除协程内网络通信器
|
||||
* @param netThreadSeq
|
||||
*/
|
||||
void eraseSchedCommunicatorEpoll(size_t netThreadSeq);
|
||||
|
||||
/**
|
||||
* 框架内部需要直接访问通信器的类
|
||||
*/
|
||||
|
@ -319,7 +416,7 @@ protected:
|
|||
|
||||
friend class CommunicatorEpoll;
|
||||
|
||||
friend class Transceiver;
|
||||
friend class ServantProxyThreadData;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -348,15 +445,35 @@ protected:
|
|||
ServantProxyFactory* _servantProxyFactory;
|
||||
|
||||
/*
|
||||
* 网络线程数组
|
||||
* 公有网络线程
|
||||
*/
|
||||
CommunicatorEpoll * _communicatorEpoll[MAX_CLIENT_THREAD_NUM];
|
||||
vector<shared_ptr<CommunicatorEpoll>> _communicatorEpoll;//[MAX_CLIENT_THREAD_NUM];
|
||||
|
||||
/*
|
||||
* 网络线程数目
|
||||
/**
|
||||
* 私有网络线程, 会动态变化
|
||||
*/
|
||||
size_t _clientThreadNum;
|
||||
|
||||
unordered_map<size_t, shared_ptr<CommunicatorEpoll>> _schedCommunicatorEpoll;
|
||||
|
||||
/**
|
||||
* 操作通信器的锁
|
||||
*/
|
||||
TC_SpinLock _schedMutex;
|
||||
|
||||
/**
|
||||
* 锁
|
||||
*/
|
||||
std::mutex _mutex;
|
||||
|
||||
/**
|
||||
* 条件变量, 用来等待网络线程启动
|
||||
*/
|
||||
std::condition_variable _cond;
|
||||
|
||||
/**
|
||||
* 通信器启动个数
|
||||
*/
|
||||
std::atomic<size_t> _communicatorEpollStartNum{0};
|
||||
|
||||
/*
|
||||
* 上报类
|
||||
*/
|
||||
|
@ -382,12 +499,11 @@ protected:
|
|||
*/
|
||||
unordered_map<string, shared_ptr<TC_OpenSSL::CTX>> _objCtx;
|
||||
|
||||
|
||||
/*
|
||||
* 异步线程数组
|
||||
*/
|
||||
//异步线程(跨通信器共享)
|
||||
vector<AsyncProcThread*> _asyncThread;//[MAX_THREAD_NUM];
|
||||
vector<AsyncProcThread*> _asyncThread;
|
||||
|
||||
/*
|
||||
* 异步队列的统计上报的对象
|
||||
|
@ -402,21 +518,26 @@ protected:
|
|||
* 分发给异步线程的索引seq
|
||||
*/
|
||||
size_t _asyncSeq = 0;
|
||||
|
||||
/**
|
||||
* 注册事件
|
||||
*/
|
||||
size_t _sigId = -1;
|
||||
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// public:
|
||||
// struct TraceManager:public TC_HandleBase{
|
||||
// zipkin::ZipkinOtTracerOptions _zipkin_options;
|
||||
// std::shared_ptr<opentracing::Tracer> _tracer;
|
||||
// TraceManager(): _tracer(nullptr){}
|
||||
// TraceManager(zipkin::ZipkinOtTracerOptions& options):_zipkin_options(options){
|
||||
// _tracer = zipkin::makeZipkinOtTracer(options);
|
||||
// }
|
||||
// ~TraceManager(){if(_tracer != nullptr){_tracer->Close();}}
|
||||
// };
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
public:
|
||||
struct TraceManager:public TC_HandleBase{
|
||||
zipkin::ZipkinOtTracerOptions _zipkin_options;
|
||||
std::shared_ptr<opentracing::Tracer> _tracer;
|
||||
TraceManager(): _tracer(nullptr){}
|
||||
TraceManager(zipkin::ZipkinOtTracerOptions& options):_zipkin_options(options){
|
||||
_tracer = zipkin::makeZipkinOtTracer(options);
|
||||
}
|
||||
~TraceManager(){if(_tracer != nullptr){_tracer->Close();}}
|
||||
};
|
||||
|
||||
TC_AutoPtr<TraceManager> _traceManager;
|
||||
#endif
|
||||
// TC_AutoPtr<TraceManager> _traceManager;
|
||||
// #endif
|
||||
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "util/tc_loop_queue.h"
|
||||
#include "servant/Message.h"
|
||||
#include "servant/EndpointInfo.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/Communicator.h"
|
||||
#include <set>
|
||||
|
||||
namespace tars
|
||||
|
@ -30,7 +32,6 @@ namespace tars
|
|||
|
||||
class Communicator;
|
||||
class ObjectProxy;
|
||||
class ObjectProxyFactory;
|
||||
class StatReport;
|
||||
class PropertyReport;
|
||||
|
||||
|
@ -38,23 +39,12 @@ class PropertyReport;
|
|||
/**
|
||||
* 监听FD事件并触发注册的handle
|
||||
*/
|
||||
struct FDInfo
|
||||
struct FDInfo
|
||||
{
|
||||
enum
|
||||
{
|
||||
ET_C_NOTIFY = 1,
|
||||
ET_C_NET = 2,
|
||||
ET_C_TERMINATE = 3,
|
||||
ET_C_UPDATE_LIST= 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
FDInfo()
|
||||
: iSeq(0)
|
||||
, iType(ET_C_NOTIFY)
|
||||
, p(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,33 +53,36 @@ struct FDInfo
|
|||
*/
|
||||
~FDInfo()
|
||||
{
|
||||
if (msgQueue)
|
||||
{
|
||||
ReqMessage *msg;
|
||||
while (msgQueue->pop_front(msg))
|
||||
{
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t iSeq;
|
||||
int iType;
|
||||
void * p;
|
||||
shared_ptr<ReqInfoQueue> msgQueue;
|
||||
TC_Epoller::NotifyInfo notify;
|
||||
};
|
||||
|
||||
struct UpdateListInfo
|
||||
{
|
||||
ServantPrx prx;
|
||||
set<EndpointInfo> active;
|
||||
set<EndpointInfo> inactive;
|
||||
bool autoDestroy = false;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 客户端网络处理的线程类
|
||||
*/
|
||||
class CommunicatorEpoll : public TC_Thread ,public TC_ThreadRecMutex
|
||||
class CommunicatorEpoll : public TC_Thread, public enable_shared_from_this<CommunicatorEpoll>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param pCommunicator
|
||||
* @param netThreadSeq, 业务线程序号, 如果是公有网络通信器, 则为-1
|
||||
* @param isFirst, 是否是第一个公有网络通信器
|
||||
*/
|
||||
CommunicatorEpoll(Communicator * pCommunicator, size_t _netThreadSeq);
|
||||
CommunicatorEpoll(Communicator * pCommunicator, size_t netThreadSeq, bool isFirst = false);
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
|
@ -104,18 +97,10 @@ public:
|
|||
return _communicator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ObjectProxyFactory
|
||||
*/
|
||||
inline ObjectProxyFactory * getObjectProxyFactory()
|
||||
{
|
||||
return _objectProxyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 网络线程id
|
||||
*/
|
||||
inline size_t getCommunicatorEpollId()
|
||||
inline size_t getCommunicatorNetThreadSeq()
|
||||
{
|
||||
return _netThreadSeq;
|
||||
}
|
||||
|
@ -133,13 +118,27 @@ public:
|
|||
*/
|
||||
inline bool isFirstNetThread()
|
||||
{
|
||||
return (_netThreadSeq == 0);
|
||||
return _isFirst;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取epoller
|
||||
* @return
|
||||
*/
|
||||
inline TC_Epoller* getEpoller() { return _epoller; }
|
||||
|
||||
/**
|
||||
* 是否存在ObjectProxy了, 如果已经存在则创建
|
||||
* @param sObjectProxyName
|
||||
* @param setName
|
||||
* @return
|
||||
*/
|
||||
ObjectProxy * hasObjectProxy(const string & sObjectProxyName,const string& setName="");
|
||||
|
||||
/*
|
||||
* 获取本epoll的代理对象
|
||||
*/
|
||||
ObjectProxy * getObjectProxy(const string & sObjectProxyName,const string& setName="");
|
||||
ObjectProxy * createObjectProxy(ServantProxy *servantProxy, const string & sObjectProxyName,const string& setName="");
|
||||
|
||||
/**
|
||||
* 循环监听网络事件
|
||||
|
@ -153,83 +152,138 @@ public:
|
|||
|
||||
/**
|
||||
* 注册fd对应的处理handle
|
||||
* @param fd
|
||||
* @param info 事件指针
|
||||
* @param event
|
||||
* @param handle
|
||||
* @param adapterProxy
|
||||
*/
|
||||
int addFd(int fd,FDInfo * info, uint32_t events);
|
||||
|
||||
/**
|
||||
* 取消已注册的handle
|
||||
* @param fd
|
||||
* @param info 事件指针
|
||||
* @param event
|
||||
* @param handle
|
||||
*/
|
||||
int delFd(int fd,FDInfo * info, uint32_t events);
|
||||
|
||||
/**
|
||||
* mod handle
|
||||
* @param fd
|
||||
* @param info
|
||||
* @param events
|
||||
* @return
|
||||
*/
|
||||
int modFd(int fd,FDInfo * info, uint32_t events);
|
||||
void addFd(AdapterProxy* adapterProxy);
|
||||
|
||||
/**
|
||||
* 通知事件过来
|
||||
* @param iSeq
|
||||
*/
|
||||
void notify(size_t iSeq,ReqInfoQueue * pReqQueue);
|
||||
void notifyDel(size_t iSeq);
|
||||
void notify(size_t iSeq);
|
||||
|
||||
/**
|
||||
* 主动更新ip list
|
||||
* @param active
|
||||
* @param inactive
|
||||
*/
|
||||
void notifyUpdateEndpoints(const ServantPrx &prx, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive);
|
||||
void notifyUpdateEndpoints(ServantProxy *servantProxy, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive);
|
||||
|
||||
/**
|
||||
* 数据加入到异步线程队列里面
|
||||
* @return
|
||||
*/
|
||||
void pushAsyncThreadQueue(ReqMessage * msg);
|
||||
inline void pushAsyncThreadQueue(ReqMessage * msg) { _communicator->pushAsyncThreadQueue(msg); }
|
||||
|
||||
/**
|
||||
* set reconnect
|
||||
* @param time
|
||||
*/
|
||||
void reConnect(int64_t ms, Transceiver*);
|
||||
inline void reConnect(int64_t ms, TC_Transceiver*p) { _reconnect[ms] = p; }
|
||||
|
||||
/**
|
||||
* communicator resource desc
|
||||
* @return
|
||||
*/
|
||||
string getResourcesInfo();
|
||||
void getResourcesInfo(ostringstream &desc);
|
||||
|
||||
/**
|
||||
* 所有对象代理加载locator信息
|
||||
*/
|
||||
int loadObjectLocator();
|
||||
|
||||
/**
|
||||
* servant换成对应线程的objectproxy
|
||||
* @param servantProxy
|
||||
* @return
|
||||
*/
|
||||
ObjectProxy* servantToObjectProxy(ServantProxy *servantProxy);
|
||||
|
||||
/**
|
||||
* 是否是协程中的私有通信器
|
||||
* @return
|
||||
*/
|
||||
inline bool isSchedCommunicatorEpoll() const { return !_public; }
|
||||
|
||||
/**
|
||||
* 初始化notify
|
||||
*/
|
||||
void initNotify(size_t iSeq, const shared_ptr<ReqInfoQueue> &msgQueue);
|
||||
|
||||
/**
|
||||
* 直接通知
|
||||
*/
|
||||
inline void handle(uint16_t reqQNo) { handleNotify(_notify[reqQNo]->notify.getEpollInfo()); }
|
||||
|
||||
/**
|
||||
* 获取通知句柄(主要用于测试)
|
||||
* @return
|
||||
*/
|
||||
FDInfo** getNotify() { return _notify; }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 网络线程中处理CommunicatorEpoll退出的清理逻辑
|
||||
*/
|
||||
void handleTerminate();
|
||||
|
||||
/**
|
||||
* 通知CommunicatorEpoll退出
|
||||
*/
|
||||
void notifyTerminate();
|
||||
|
||||
/**
|
||||
* 网络线程中处理业务线程退出的清理逻辑
|
||||
*/
|
||||
void handleServantThreadQuit(uint16_t iSeq);
|
||||
|
||||
/**
|
||||
* 通知业务线程退出
|
||||
*/
|
||||
void notifyServantThreadQuit(uint16_t iSeq);
|
||||
|
||||
/**
|
||||
* 处理函数
|
||||
*
|
||||
* @param pFDInfo
|
||||
* @param events
|
||||
* 初始化
|
||||
* 如果在其他协程中, 并不自己run, 只需要调用该函数初始化epoller即可
|
||||
*/
|
||||
void handle(FDInfo * pFDInfo, const epoll_event &ev);
|
||||
void initializeEpoller();
|
||||
|
||||
/**
|
||||
* 上报数据
|
||||
* @param pmStatMicMsg
|
||||
*/
|
||||
void report(StatReport::MapStatMicMsg *pmStatMicMsg);
|
||||
|
||||
/**
|
||||
* 弹出来统计数据
|
||||
* @param mStatMsg
|
||||
* @return
|
||||
*/
|
||||
bool popStatMsg(StatReport::MapStatMicMsg* &mStatMsg);
|
||||
|
||||
/**
|
||||
* 输入事件
|
||||
* @param pi
|
||||
*/
|
||||
void handleInputImp(Transceiver * pTransceiver);
|
||||
bool handleCloseImp(const shared_ptr<TC_Epoller::EpollInfo> &data);
|
||||
|
||||
/**
|
||||
* 输入事件
|
||||
* @param pi
|
||||
*/
|
||||
bool handleInputImp(const shared_ptr<TC_Epoller::EpollInfo> &data);
|
||||
|
||||
/**
|
||||
* 输出事件
|
||||
* @param pi
|
||||
*/
|
||||
void handleOutputImp(Transceiver * pTransceiver);
|
||||
bool handleOutputImp(const shared_ptr<TC_Epoller::EpollInfo> &data);
|
||||
|
||||
/**
|
||||
* 处理notify
|
||||
*/
|
||||
bool handleNotify(const shared_ptr<TC_Epoller::EpollInfo> & data);
|
||||
|
||||
/**
|
||||
* 处理超时
|
||||
|
@ -246,8 +300,38 @@ protected:
|
|||
/**
|
||||
* reconnect
|
||||
*/
|
||||
void reConnect();
|
||||
void doReconnect();
|
||||
|
||||
/**
|
||||
* 根据序号 获取所有obj对象
|
||||
*/
|
||||
inline ObjectProxy * getObjectProxy(size_t iNum)
|
||||
{
|
||||
TC_ThreadRLock lock(_vObjectMutex);
|
||||
|
||||
assert(iNum < _objNum);
|
||||
return _vObjectProxys[iNum];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有对象的个数,为了不加锁不用map
|
||||
*/
|
||||
inline size_t getObjNum()
|
||||
{
|
||||
return _objNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要上报的stat数据size
|
||||
* @return
|
||||
*/
|
||||
inline size_t getReportSize() { return _statQueue.size(); }
|
||||
|
||||
friend class StatReport;
|
||||
friend class AdapterProxy;
|
||||
friend class Communicator;
|
||||
friend class ServantProxy;
|
||||
friend class ServantProxyThreadData;
|
||||
protected:
|
||||
/*
|
||||
* 通信器
|
||||
|
@ -255,42 +339,73 @@ protected:
|
|||
Communicator * _communicator;
|
||||
|
||||
/**
|
||||
* notify
|
||||
* 是否第一个网络线程
|
||||
*/
|
||||
FDInfo* _notify[MAX_CLIENT_NOTIFYEVENT_NUM];
|
||||
|
||||
/*
|
||||
* terminate thread
|
||||
*/
|
||||
bool _terminate;
|
||||
bool _isFirst = false;
|
||||
|
||||
/**
|
||||
* terminate fd info
|
||||
* 是否公有的网络线程
|
||||
*/
|
||||
FDInfo _terminateFDInfo;
|
||||
bool _public = false;
|
||||
|
||||
/*
|
||||
/**
|
||||
* notify
|
||||
*/
|
||||
FDInfo* _notify[MAX_CLIENT_NOTIFYEVENT_NUM];
|
||||
|
||||
/**
|
||||
* schedule
|
||||
*/
|
||||
shared_ptr<TC_CoroutineScheduler> _scheduler;
|
||||
|
||||
/**
|
||||
* 独立的网络线程存在, 线程私有数据
|
||||
*/
|
||||
ServantProxyThreadData *_pSptd = NULL;
|
||||
|
||||
/*
|
||||
* epoll
|
||||
*/
|
||||
TC_Epoller _ep;
|
||||
TC_Epoller *_epoller = NULL;
|
||||
|
||||
/**
|
||||
* lock
|
||||
*/
|
||||
TC_ThreadRecMutex _objectMutex;
|
||||
|
||||
/**
|
||||
* 保存已创建的objectproxy
|
||||
*/
|
||||
unordered_map<string, ObjectProxy*> _objectProxys;
|
||||
|
||||
/**
|
||||
* _vObjectProxys读写锁
|
||||
*/
|
||||
TC_ThreadRWLocker _vObjectMutex;
|
||||
|
||||
/**
|
||||
* 保存已经创建的obj 取的时候可以不用加锁
|
||||
*/
|
||||
vector<ObjectProxy *> _vObjectProxys;
|
||||
|
||||
/**
|
||||
* 读写锁
|
||||
*/
|
||||
TC_ThreadRWLocker _servantMutex;
|
||||
|
||||
/**
|
||||
* servant对应的objectProxy
|
||||
*/
|
||||
unordered_map<ServantProxy*, ObjectProxy*> _servantObjectProxy;
|
||||
|
||||
/*
|
||||
* 下次检查超时的时间
|
||||
*保存已经创建obj的数量
|
||||
*/
|
||||
int64_t _nextTime;
|
||||
|
||||
/*
|
||||
* 下次上报数据的时间
|
||||
*/
|
||||
int64_t _nextStatTime;
|
||||
|
||||
/*
|
||||
* ObjectProxy的工厂类
|
||||
*/
|
||||
ObjectProxyFactory * _objectProxyFactory;
|
||||
size_t _objNum = 0;
|
||||
|
||||
/*
|
||||
* 网络线程的id号
|
||||
* 私有网络线程: ServantProxyThreadData::_reqQNo, 从0开始计数
|
||||
*/
|
||||
size_t _netThreadSeq;
|
||||
|
||||
|
@ -305,9 +420,29 @@ protected:
|
|||
int64_t _timeoutCheckInterval;
|
||||
|
||||
/**
|
||||
* auto reconnect Transceiver
|
||||
* auto reconnect TC_Transceiver
|
||||
*/
|
||||
map<int64_t, Transceiver*> _reconnect;
|
||||
unordered_map<int64_t, TC_Transceiver*> _reconnect;
|
||||
|
||||
/**
|
||||
* 统计数据
|
||||
*/
|
||||
TC_LoopQueue<StatReport::MapStatMicMsg*> _statQueue;
|
||||
|
||||
/**
|
||||
* 网络线程ID
|
||||
*/
|
||||
std::thread::id _threadId;
|
||||
|
||||
/**
|
||||
* 定时器的id
|
||||
*/
|
||||
vector<int64_t> _timerIds;
|
||||
|
||||
/**
|
||||
* 锁
|
||||
*/
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
assert(NULL != td);
|
||||
if (td)
|
||||
{
|
||||
td->_cookie.clear();
|
||||
td->_data._cookie.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
|
||||
return td->_cookie;
|
||||
return td->_data._cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
assert(NULL != td);
|
||||
if(td)
|
||||
{
|
||||
td->_cookie = cookie;
|
||||
td->_data._cookie = cookie;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,704 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _COROUTINES_SCHEDULLER_H_
|
||||
#define _COROUTINES_SCHEDULLER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include "util/tc_platform.h"
|
||||
#include "util/tc_fcontext.h"
|
||||
#include "util/tc_cas_queue.h"
|
||||
#include "util/tc_monitor.h"
|
||||
#include <functional>
|
||||
#include "util/tc_thread.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace tars
|
||||
{
|
||||
class ServantHandle;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/**
|
||||
* 协程使用的栈内容信息
|
||||
*/
|
||||
struct stack_context
|
||||
{
|
||||
std::size_t size;
|
||||
void* sp;
|
||||
|
||||
stack_context()
|
||||
: size(0)
|
||||
, sp(0)
|
||||
{}
|
||||
};
|
||||
|
||||
struct stack_traits
|
||||
{
|
||||
static bool is_unbounded();
|
||||
|
||||
static std::size_t page_size();
|
||||
|
||||
static std::size_t default_size();
|
||||
|
||||
static std::size_t minimum_size();
|
||||
|
||||
static std::size_t maximum_size();
|
||||
|
||||
static stack_context allocate(std::size_t);
|
||||
|
||||
static void deallocate( stack_context &);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/**
|
||||
* 协程的状态信息
|
||||
*/
|
||||
enum CORO_STATUS
|
||||
{
|
||||
CORO_FREE = 0,
|
||||
CORO_ACTIVE = 1,
|
||||
CORO_AVAIL = 2,
|
||||
CORO_INACTIVE = 3,
|
||||
CORO_TIMEOUT = 4
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
/*
|
||||
* 协程内部使用的函数
|
||||
*/
|
||||
// typedef void( * Func)(void *);
|
||||
typedef void( * Func)(void *, transfer_t);
|
||||
struct CoroutineFunc
|
||||
{
|
||||
Func coroFunc;
|
||||
void* args;
|
||||
};
|
||||
|
||||
class CoroutineScheduler;
|
||||
|
||||
///////////////////////////////////////////
|
||||
/**
|
||||
* 协程信息类
|
||||
*/
|
||||
class CoroutineInfo
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 链表初始化
|
||||
*/
|
||||
static inline void CoroutineHeadInit(CoroutineInfo *coro)
|
||||
{
|
||||
coro->_next = coro;
|
||||
coro->_prev = coro;
|
||||
}
|
||||
|
||||
/**
|
||||
* 链表是否为空
|
||||
*/
|
||||
static inline bool CoroutineHeadEmpty(CoroutineInfo *coro_head)
|
||||
{
|
||||
return coro_head->_next == coro_head;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入
|
||||
*/
|
||||
static inline void __CoroutineAdd(CoroutineInfo *coro, CoroutineInfo *prev, CoroutineInfo *next)
|
||||
{
|
||||
next->_prev = coro;
|
||||
coro->_next = next;
|
||||
coro->_prev = prev;
|
||||
prev->_next = coro;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入头部
|
||||
*/
|
||||
static inline void CoroutineAdd(CoroutineInfo *new_coro, CoroutineInfo *coro_head)
|
||||
{
|
||||
__CoroutineAdd(new_coro, coro_head, coro_head->_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入尾部
|
||||
*/
|
||||
static inline void CoroutineAddTail(CoroutineInfo *new_coro, CoroutineInfo *coro_head)
|
||||
{
|
||||
__CoroutineAdd(new_coro, coro_head->_prev, coro_head);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
static inline void __CoroutineDel(CoroutineInfo * prev, CoroutineInfo * next)
|
||||
{
|
||||
next->_prev = prev;
|
||||
prev->_next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
static inline void CoroutineDel(CoroutineInfo *coro)
|
||||
{
|
||||
__CoroutineDel(coro->_prev, coro->_next);
|
||||
coro->_next = NULL;
|
||||
coro->_prev = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从一个链表移动到另外一个链表头部
|
||||
*/
|
||||
static inline void CoroutineMove(CoroutineInfo *coro, CoroutineInfo *coro_head)
|
||||
{
|
||||
CoroutineDel(coro);
|
||||
CoroutineAdd(coro, coro_head);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从一个链表移动到另外一个链表尾部
|
||||
*/
|
||||
static inline void CoroutineMoveTail(CoroutineInfo *coro, CoroutineInfo *coro_head)
|
||||
{
|
||||
CoroutineDel(coro);
|
||||
CoroutineAddTail(coro, coro_head);
|
||||
}
|
||||
|
||||
protected:
|
||||
//协程的入口函数
|
||||
static void corotineEntry(transfer_t q);
|
||||
|
||||
//在协程里执行实际逻辑的入口函数
|
||||
static void corotineProc(void * args, transfer_t t);
|
||||
|
||||
public:
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
CoroutineInfo();
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
CoroutineInfo(CoroutineScheduler* scheduler);
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
CoroutineInfo(CoroutineScheduler* scheduler, uint32_t iUid, stack_context stack_ctx);
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
~CoroutineInfo();
|
||||
|
||||
/**
|
||||
* 注册协程实际的处理函数
|
||||
*/
|
||||
void registerFunc(const std::function<void ()> &callback);
|
||||
|
||||
/**
|
||||
* 设置协程的内存空间
|
||||
*/
|
||||
void setStackContext(stack_context stack_ctx);
|
||||
|
||||
/**
|
||||
* 获取协程的内存空间
|
||||
*/
|
||||
inline stack_context& getStackContext() { return _stack_ctx; }
|
||||
|
||||
/**
|
||||
* 获取协程所处的调度器
|
||||
*/
|
||||
inline CoroutineScheduler* getScheduler() { return _scheduler; }
|
||||
|
||||
/**
|
||||
* 获取协程的标志
|
||||
*/
|
||||
inline uint32_t getUid() { return _uid; }
|
||||
|
||||
/**
|
||||
* 设置协程的标志
|
||||
*/
|
||||
inline void setUid(uint32_t iUid) { _uid = iUid; }
|
||||
|
||||
/**
|
||||
* 获取协程的状态
|
||||
*/
|
||||
inline CORO_STATUS getStatus() { return _eStatus; }
|
||||
|
||||
/**
|
||||
* 设置协程的状态
|
||||
*/
|
||||
inline void setStatus(CORO_STATUS status) { _eStatus = status; }
|
||||
|
||||
/**
|
||||
* 获取协程所处的上下文
|
||||
*/
|
||||
inline fcontext_t getCtx() { return _ctx; }
|
||||
inline void setCtx(fcontext_t ctx) { _ctx = ctx; }
|
||||
public:
|
||||
/*
|
||||
* 双向链表指针
|
||||
*/
|
||||
CoroutineInfo* _prev;
|
||||
CoroutineInfo* _next;
|
||||
|
||||
private:
|
||||
/*
|
||||
* 是否是主协程
|
||||
*/
|
||||
// bool _main;
|
||||
|
||||
/*
|
||||
* 协程所属的调度器
|
||||
*/
|
||||
CoroutineScheduler* _scheduler;
|
||||
|
||||
/*I
|
||||
* 协程的标识
|
||||
*/
|
||||
uint32_t _uid;
|
||||
|
||||
/*
|
||||
* 协程的状态
|
||||
*/
|
||||
CORO_STATUS _eStatus;
|
||||
|
||||
/*
|
||||
* 协程的内存空间
|
||||
*/
|
||||
stack_context _stack_ctx;
|
||||
|
||||
/*
|
||||
* 创建协程后,协程所在的上下文
|
||||
*/
|
||||
fcontext_t _ctx;
|
||||
|
||||
/*
|
||||
* 协程初始化函数入口函数
|
||||
*/
|
||||
CoroutineFunc _init_func;
|
||||
|
||||
/*
|
||||
* 协程具体执行函数
|
||||
*/
|
||||
std::function<void ()> _callback;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
/**
|
||||
* 协程调度类
|
||||
*/
|
||||
class CoroutineScheduler
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
CoroutineScheduler();
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
~CoroutineScheduler();
|
||||
|
||||
/**
|
||||
* 初始化协程池的大小、以及协程的堆栈大小
|
||||
*/
|
||||
void init(uint32_t iPoolSize, size_t iStackSize);
|
||||
|
||||
/**
|
||||
* 创建协程
|
||||
*/
|
||||
uint32_t createCoroutine(const std::function<void ()> &callback);
|
||||
|
||||
/**
|
||||
* 在用户自己起的线程中使用协程时,用到的协程调度
|
||||
*/
|
||||
void run();
|
||||
|
||||
/**
|
||||
* tars框架业务线程使用协程时,用的协程调度
|
||||
*/
|
||||
void tars_run();
|
||||
|
||||
/**
|
||||
* 当前协程放弃继续执行
|
||||
*/
|
||||
void yield(bool bFlag = true);
|
||||
|
||||
/**
|
||||
* 当前协程休眠iSleepTime时间(单位:毫秒),然后会被唤醒继续执行
|
||||
*/
|
||||
void sleep(int iSleepTime);
|
||||
|
||||
/**
|
||||
* 放入需要唤醒的协程
|
||||
*/
|
||||
void put(uint32_t iCoroId);
|
||||
|
||||
/**
|
||||
* 协程切换
|
||||
*/
|
||||
// void switchCoro(CoroutineInfo *from, CoroutineInfo *to);
|
||||
void switchCoro(CoroutineInfo *to);
|
||||
|
||||
/**
|
||||
* 停止
|
||||
*/
|
||||
void terminate();
|
||||
|
||||
/**
|
||||
* 资源销毁
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* 获取最大的协程数目
|
||||
*/
|
||||
inline uint32_t getPoolSize() { return _poolSize; }
|
||||
|
||||
/**
|
||||
* 获取当前已经创建的协程数目
|
||||
*/
|
||||
inline uint32_t getCurrentSize() { return _currentSize; }
|
||||
|
||||
/**
|
||||
* 获取请求响应回来的协程数目
|
||||
*/
|
||||
inline size_t getResponseCoroSize() { return _activeCoroQueue.size(); }
|
||||
|
||||
/**
|
||||
* 获取框架业务线程的Handle
|
||||
*/
|
||||
inline ServantHandle* getHandle() { return _handle; }
|
||||
|
||||
/**
|
||||
* 设置框架业务线程的Handle
|
||||
*/
|
||||
inline void setHandle(ServantHandle* handle) { _handle = handle; }
|
||||
|
||||
/**
|
||||
* 获取理论上空闲的协程数目
|
||||
*/
|
||||
inline uint32_t getFreeSize() { return _poolSize - _usedSize; }
|
||||
|
||||
/**
|
||||
* 减少正在使用的协程数目
|
||||
*/
|
||||
inline void decUsedSize() { --_usedSize; }
|
||||
|
||||
/**
|
||||
* 增加正在使用的协程数目
|
||||
*/
|
||||
inline void incUsedSize() { ++_usedSize; }
|
||||
|
||||
/**
|
||||
* 调度器中的主协程
|
||||
*/
|
||||
inline CoroutineInfo& getMainCoroutine() { return _mainCoro; }
|
||||
|
||||
/**
|
||||
* 设置主协程
|
||||
*/
|
||||
inline void setMainCtx(fcontext_t ctx) { _mainCoro.setCtx(ctx); }
|
||||
|
||||
/**
|
||||
* 当前协程的标识Id
|
||||
*/
|
||||
inline uint32_t getCoroutineId() { return _currentCoro->getUid(); }
|
||||
|
||||
friend class CoroutineInfo;
|
||||
|
||||
private:
|
||||
/**
|
||||
* 产生协程id
|
||||
*/
|
||||
uint32_t generateId();
|
||||
|
||||
/**
|
||||
* 增加协程池的大小
|
||||
*/
|
||||
int increaseCoroPoolSize();
|
||||
|
||||
/**
|
||||
* 唤醒需要运行的协程
|
||||
*/
|
||||
void wakeup();
|
||||
|
||||
/**
|
||||
* 唤醒自己放弃运行的协程
|
||||
*/
|
||||
void wakeupbyself();
|
||||
|
||||
/**
|
||||
* 自己放弃运行时,用到
|
||||
*/
|
||||
void putbyself(uint32_t iCoroId);
|
||||
|
||||
/**
|
||||
* 唤醒休眠的协程
|
||||
*/
|
||||
int wakeupbytimeout();
|
||||
|
||||
/**
|
||||
* 放到active的协程链表中
|
||||
*/
|
||||
void moveToActive(CoroutineInfo *coro, bool bFlag = false);
|
||||
|
||||
/**
|
||||
* 放到avail的协程链表中
|
||||
*/
|
||||
void moveToAvail(CoroutineInfo *coro);
|
||||
|
||||
/**
|
||||
* 放到inactive的协程链表中
|
||||
*/
|
||||
void moveToInactive(CoroutineInfo *coro);
|
||||
|
||||
/**
|
||||
* 放到超时等待的协程链表中
|
||||
*/
|
||||
void moveToTimeout(CoroutineInfo *coro);
|
||||
|
||||
/**
|
||||
* 放到空闲的协程链表中
|
||||
*/
|
||||
void moveToFreeList(CoroutineInfo *coro);
|
||||
|
||||
private:
|
||||
/*
|
||||
* 是否停止运行
|
||||
*/
|
||||
bool _terminal;
|
||||
|
||||
/*
|
||||
* 协程池的大小
|
||||
*/
|
||||
uint32_t _poolSize;
|
||||
|
||||
/*
|
||||
* 协程的栈空间大小
|
||||
*/
|
||||
size_t _stackSize;
|
||||
|
||||
/*
|
||||
* 当前已经创建的协程数
|
||||
*/
|
||||
uint32_t _currentSize;
|
||||
|
||||
/*
|
||||
* 正在使用的协程数
|
||||
*/
|
||||
uint32_t _usedSize;
|
||||
|
||||
/*
|
||||
* 产生协程Id的变量
|
||||
*/
|
||||
uint32_t _uniqId;
|
||||
|
||||
/*
|
||||
* 框架的ServantHandle类
|
||||
*/
|
||||
ServantHandle* _handle;
|
||||
|
||||
/*
|
||||
* 主协程
|
||||
*/
|
||||
CoroutineInfo _mainCoro;
|
||||
|
||||
/*
|
||||
* 当前运行的协程
|
||||
*/
|
||||
CoroutineInfo* _currentCoro;
|
||||
|
||||
/*
|
||||
* 存放所有协程的数组指针
|
||||
*/
|
||||
CoroutineInfo** _all_coro;
|
||||
|
||||
/*
|
||||
* 活跃的协程链表
|
||||
*/
|
||||
CoroutineInfo _active;
|
||||
|
||||
/*
|
||||
* 可用的协程链表
|
||||
*/
|
||||
CoroutineInfo _avail;
|
||||
|
||||
/*
|
||||
* 不活跃的协程链表
|
||||
*/
|
||||
CoroutineInfo _inactive;
|
||||
|
||||
/*
|
||||
* 超时的协程链表
|
||||
*/
|
||||
CoroutineInfo _timeout;
|
||||
|
||||
/*
|
||||
* 空闲的协程链表
|
||||
*/
|
||||
CoroutineInfo _free;
|
||||
|
||||
/*
|
||||
* 需要激活的协程队列,其他线程使用,用来激活等待结果的协程
|
||||
*/
|
||||
TC_CasQueue<uint32_t, deque<uint32_t> > _activeCoroQueue;
|
||||
|
||||
/*
|
||||
* 锁通知
|
||||
*/
|
||||
TC_ThreadLock _monitor;
|
||||
|
||||
/*
|
||||
* 需要激活的协程队列,本线程使用
|
||||
*/
|
||||
list<uint32_t> _needActiveCoroId;
|
||||
|
||||
/*
|
||||
* 存放超时的协程
|
||||
*/
|
||||
multimap<int64_t, uint32_t> _timeoutCoroId;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* @brief 协程异常类
|
||||
*/
|
||||
struct CoroutineException : public TC_Exception
|
||||
{
|
||||
CoroutineException(const string &buffer) : TC_Exception(buffer){};
|
||||
CoroutineException(const string &buffer, int err) : TC_Exception(buffer, err){};
|
||||
~CoroutineException() throw() {};
|
||||
};
|
||||
|
||||
//对线程进行包装的协程类,主要用于在自己起的线程中使用协程,业务可以继承这个类
|
||||
class Coroutine : public TC_Thread
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
Coroutine();
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
virtual ~Coroutine();
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @iNum, 表示要运行多个协程,即会有这个类多少个coroRun运行
|
||||
* @iTotalNum,表示这个线程最多包含的协程个数
|
||||
* @iStackSize,协程的栈大小
|
||||
*/
|
||||
void setCoroInfo(uint32_t iNum, uint32_t iMaxNum, size_t iStackSize);
|
||||
|
||||
/**
|
||||
* 创建协程,在已经创建的协程中使用
|
||||
* 返回值为协程的id,大于0,表示成功,,小于等于0,表示失败
|
||||
*/
|
||||
uint32_t createCoroutine(const std::function<void ()> &coroFunc);
|
||||
|
||||
/**
|
||||
* 当前协程自己放弃执行,会自动被调度器唤醒
|
||||
* 在已经创建的协程中使用
|
||||
*/
|
||||
void yield();
|
||||
|
||||
/**
|
||||
* 当前协程休眠iSleepTime时间(单位:毫秒),时间到了,会自动被调度器唤醒
|
||||
* 在已经创建的协程中使用
|
||||
*/
|
||||
void Sleep(int iSleepTime);
|
||||
|
||||
/**
|
||||
* 返回协程调度类的指针
|
||||
*/
|
||||
CoroutineScheduler * getCoroSched() { return _coroSched; }
|
||||
|
||||
/**
|
||||
* 获取设置的最大协程的数目
|
||||
*/
|
||||
uint32_t getMaxCoroNum() { return _maxNum; }
|
||||
|
||||
/**
|
||||
* 获取启动时,设置的协程的数目
|
||||
*/
|
||||
uint32_t getCoroNum() { return _num; }
|
||||
|
||||
/**
|
||||
* 设置协程的栈大小
|
||||
*/
|
||||
size_t getCoroStackSize() { return _stackSize; }
|
||||
|
||||
/**
|
||||
* 停止
|
||||
*/
|
||||
void terminate();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 线程处理方法
|
||||
*/
|
||||
virtual void run();
|
||||
|
||||
/**
|
||||
* 静态函数, 协程入口.
|
||||
*/
|
||||
static void coroEntry(Coroutine *pCoro);
|
||||
|
||||
/**
|
||||
* 协程运行的函数,根据_num的数目,会启动_num个这个函数
|
||||
*/
|
||||
virtual void handle() = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 线程已经启动, 进入协程处理前调用
|
||||
*/
|
||||
virtual void initialize() {}
|
||||
|
||||
/**
|
||||
* 所有协程停止运行之后,线程退出之前时调用
|
||||
*/
|
||||
virtual void destroy() {}
|
||||
|
||||
/**
|
||||
* 具体的处理逻辑
|
||||
*/
|
||||
virtual void handleCoro();
|
||||
|
||||
private:
|
||||
CoroutineScheduler *_coroSched;
|
||||
uint32_t _num;
|
||||
uint32_t _maxNum;
|
||||
size_t _stackSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -191,8 +191,14 @@ public:
|
|||
*/
|
||||
void setReportStat(bool bReport);
|
||||
|
||||
/**
|
||||
* 获取RequestPacket
|
||||
* @return
|
||||
*/
|
||||
const RequestPacket &getBasePacket() const { return _request; }
|
||||
|
||||
/**
|
||||
* taf协议的发送响应数据(仅TAF协议有效)
|
||||
* tars协议的发送响应数据(仅TARS协议有效)
|
||||
* @param iRet
|
||||
* @param status
|
||||
* @param buffer
|
||||
|
@ -200,7 +206,7 @@ public:
|
|||
void sendResponse(int iRet);
|
||||
|
||||
/**
|
||||
* taf协议的发送响应数据(仅TAF协议有效), 直接swapbuffer , 这样可以不用copy 数据
|
||||
* tars协议的发送响应数据(仅TARS协议有效), 直接swapbuffer , 这样可以不用copy 数据
|
||||
* @param iRet
|
||||
* @param status
|
||||
* @param buffer
|
||||
|
@ -208,7 +214,7 @@ public:
|
|||
void sendResponse(int iRet, tars::TarsOutputStream<tars::BufferWriterVector>& os);
|
||||
|
||||
/**
|
||||
* taf协议的发送响应数据(仅TAF协议有效), 直接swapbuffer , 这样可以不用copy 数据
|
||||
* tars协议的发送响应数据(仅TARS协议有效), 直接swapbuffer , 这样可以不用copy 数据
|
||||
* @param iRet
|
||||
* @param status
|
||||
* @param buffer
|
||||
|
@ -216,14 +222,21 @@ public:
|
|||
void sendResponse(int iRet, tup::UniAttribute<tars::BufferWriterVector, tars::BufferReader>& attr);
|
||||
|
||||
/**
|
||||
* taf协议的发送响应数据(仅TAF协议有效)
|
||||
* tars协议的发送响应数据(仅TARS协议有效)
|
||||
* @param iRet
|
||||
* @param buff
|
||||
*/
|
||||
void sendResponse(int iRet, const vector<char> &buff);
|
||||
|
||||
/**
|
||||
* tars协议的发送响应数据(仅TARS协议有效)
|
||||
* @param iRet
|
||||
* @param buff
|
||||
*/
|
||||
void sendResponse(int iRet, const string &buff);
|
||||
|
||||
/**
|
||||
* 普通协议的发送响应数据(非TAF协议有效)
|
||||
* 普通协议的发送响应数据(非TARS协议有效)
|
||||
* @param buff
|
||||
* @param len
|
||||
*/
|
||||
|
@ -238,6 +251,27 @@ public:
|
|||
* @param push
|
||||
*/
|
||||
void sendResponse(int iRet, ResponsePacket &response, const map<string, string>& status, const string& sResultDesc);
|
||||
/**
|
||||
* 设置调用链追踪信息,服务端主动回包时用
|
||||
* @param traceCall
|
||||
* @param traceKey
|
||||
*/
|
||||
void setTrace(bool traceCall, const string& traceKey);
|
||||
|
||||
/**
|
||||
* 是否需要追踪调用链
|
||||
*/
|
||||
bool isTraced() const;
|
||||
/**
|
||||
* 调用链追踪Key
|
||||
*/
|
||||
string getTraceKey() const;
|
||||
|
||||
/**
|
||||
* 服务器端连接是否还存在
|
||||
* @return
|
||||
*/
|
||||
bool connectionExists() const;
|
||||
protected:
|
||||
|
||||
friend class ServantHandle;
|
||||
|
@ -263,7 +297,7 @@ protected:
|
|||
void initialize(const vector<char> &sRecvBuffer);
|
||||
|
||||
/**
|
||||
* 服务端上报状态,针对单向调用及WUP调用(仅对TAF协议有效)
|
||||
* 服务端上报状态,针对单向调用及WUP调用(仅对TARS协议有效)
|
||||
*/
|
||||
void reportToStat(const string & sObj);
|
||||
|
||||
|
@ -322,7 +356,15 @@ protected:
|
|||
/**
|
||||
* cookie
|
||||
*/
|
||||
map<string, string> _cookie;
|
||||
map<string, string> _cookie;
|
||||
|
||||
/**
|
||||
* 是否是tars协议
|
||||
*/
|
||||
bool _isTars = false;
|
||||
|
||||
bool _traceCall;
|
||||
string _traceKey;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//#include "servant/Global.h"
|
||||
#include "util/tc_socket.h"
|
||||
#include "util/tc_clientsocket.h"
|
||||
#include "EndpointF.h"
|
||||
#include "servant/EndpointF.h"
|
||||
//#include "AuthF.h"
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
|
@ -61,148 +61,108 @@ public:
|
|||
* get endpoint
|
||||
* @return
|
||||
*/
|
||||
const TC_Endpoint &getEndpoint() const { return _ep; }
|
||||
inline const TC_Endpoint &getEndpoint() const { return _ep; }
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TC_Endpoint &getEndpoint() { return _ep; }
|
||||
inline TC_Endpoint &getEndpoint() { return _ep; }
|
||||
|
||||
/**
|
||||
* 设置代理地址
|
||||
* @param ep
|
||||
*/
|
||||
void setProxyEndpoint(const TC_Endpoint &ep) { _epProxy.reset(new TC_Endpoint(ep)); }
|
||||
|
||||
/**
|
||||
* 获取代理地址, 没有则为NULL
|
||||
*/
|
||||
const TC_Endpoint *getProxyEndpoint() const { return _epProxy.get(); }
|
||||
|
||||
/**
|
||||
* 获取连接地址
|
||||
* @return
|
||||
*/
|
||||
const TC_Endpoint *getConnectEndpoint() const { return _epProxy? _epProxy.get() : &_ep; }
|
||||
|
||||
/**
|
||||
* @brief is ipv6 socket or not
|
||||
* @return true if is ipv6
|
||||
*/
|
||||
bool isConnectIPv6() const { return getConnectEndpoint()->isIPv6(); }
|
||||
|
||||
/**
|
||||
* 解析域名
|
||||
*/
|
||||
void parseConnectAddress();
|
||||
|
||||
/**
|
||||
* 地址的字符串描述(用于比较)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
const string & cmpDesc() const
|
||||
{
|
||||
return _cmpDesc;
|
||||
}
|
||||
inline const string & cmpDesc() const { return _cmpDesc; }
|
||||
|
||||
/**
|
||||
* 地址的字符串描述
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
const string & desc() const
|
||||
{
|
||||
return _desc;
|
||||
}
|
||||
inline const string & desc() const { return _desc; }
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool isTcp() const;
|
||||
inline bool isTcp() const { return _ep.isTcp(); }
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
inline bool isSsl() const { return _ep.isSSL(); }
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
inline bool isUdp() const { return _ep.isUdp(); }
|
||||
|
||||
/**
|
||||
* 获取主机名
|
||||
*
|
||||
* @return const string&
|
||||
*/
|
||||
const string &host() const;
|
||||
const string &host() const { return _ep.getHost(); }
|
||||
|
||||
/**
|
||||
* 获取端口号
|
||||
*
|
||||
* @return uint16_t
|
||||
*/
|
||||
uint16_t port() const;
|
||||
uint16_t port() const { return _ep.getPort(); }
|
||||
|
||||
/**
|
||||
* 获取路由状态
|
||||
* 获取路由状态(不再使用)
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t grid() const;
|
||||
inline int32_t grid() const { return _ep.getGrid(); }
|
||||
|
||||
/*
|
||||
* 获取qos的descp值
|
||||
*/
|
||||
int32_t qos() const {return _ep.getQos();}
|
||||
inline int32_t qos() const {return _ep.getQos();}
|
||||
|
||||
/*
|
||||
* 获取节点的静态权重值
|
||||
*/
|
||||
int weight() const {return _ep.getWeight();}
|
||||
inline int weight() const {return _ep.getWeight();}
|
||||
|
||||
/**
|
||||
* @brief 获取节点的权重使用方式
|
||||
*/
|
||||
unsigned int getWeightType() const { return _ep.getWeightType(); }
|
||||
inline unsigned int getWeightType() const { return _ep.getWeightType(); }
|
||||
|
||||
// /**
|
||||
// * 获取主机地址
|
||||
// *
|
||||
// * @return const struct sockaddr_in&
|
||||
// */
|
||||
// const struct sockaddr_in& addr() const;
|
||||
|
||||
/**
|
||||
* Get ipv4 or ipv6 struct sockaddr
|
||||
*
|
||||
* @return const struct sockaddr *
|
||||
*/
|
||||
const struct sockaddr * connectAddrPtr() const;
|
||||
|
||||
/**
|
||||
* 返回端口类型
|
||||
*
|
||||
* @return EndpointInfo::EType
|
||||
*/
|
||||
TC_Endpoint::EType type() const { return _ep.getType(); }
|
||||
inline TC_Endpoint::EType type() const { return _ep.getType(); }
|
||||
|
||||
/**
|
||||
*设置set分组信息
|
||||
*
|
||||
*@return void
|
||||
*/
|
||||
void setDivision(const string& sSetDivision);
|
||||
|
||||
/**
|
||||
*返回set分组信息
|
||||
*
|
||||
*@return string
|
||||
*/
|
||||
const string& setDivision() const;
|
||||
inline const string& setDivision() const { return _setDivision; }
|
||||
|
||||
/*
|
||||
* 获取认证类型
|
||||
*/
|
||||
int authType() const { return _ep.getAuthType(); }
|
||||
inline TC_Endpoint::AUTH_TYPE authType() const { return _ep.getAuthType(); }
|
||||
|
||||
/**
|
||||
* @brief is ipv6 socket or not
|
||||
* @return true if is ipv6
|
||||
*/
|
||||
bool isIPv6() const { return _ep.isIPv6(); }
|
||||
inline bool isIPv6() const { return _ep.isIPv6(); }
|
||||
|
||||
/**
|
||||
* 等于
|
||||
|
@ -210,7 +170,7 @@ public:
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
bool operator == (const EndpointInfo& r) const;
|
||||
inline bool operator == (const EndpointInfo& r) const { return (_cmpDesc == r._cmpDesc); }
|
||||
|
||||
/**
|
||||
* 小于
|
||||
|
@ -218,7 +178,7 @@ public:
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
bool operator < (const EndpointInfo& r) const;
|
||||
inline bool operator < (const EndpointInfo& r) const { return (_cmpDesc < r._cmpDesc); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -227,7 +187,7 @@ protected:
|
|||
* @param bWithSetInfo,标识
|
||||
* @return string
|
||||
*/
|
||||
string createDesc() const;
|
||||
string createDesc() const { return _ep.toString(); }
|
||||
|
||||
/**
|
||||
* 详细地址字符串描述
|
||||
|
@ -242,24 +202,12 @@ private:
|
|||
*/
|
||||
TC_Endpoint _ep;
|
||||
|
||||
/**
|
||||
* 代理地址
|
||||
*/
|
||||
shared_ptr<TC_Endpoint> _epProxy;
|
||||
|
||||
/**
|
||||
*set分组信息
|
||||
*/
|
||||
string _setDivision;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
union
|
||||
{
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} _addr;
|
||||
|
||||
/**
|
||||
* 比较的地址字符串描述
|
||||
|
@ -272,10 +220,6 @@ private:
|
|||
string _desc;
|
||||
|
||||
|
||||
/**
|
||||
* 解析域名成功
|
||||
*/
|
||||
bool _addressSucc;
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
/*
|
||||
* 初始化
|
||||
*/
|
||||
bool init(const string & sObjName, const string & sLocator, const string& setName = "");
|
||||
bool init(const string & sObjName, const string& setName = "");
|
||||
|
||||
/*
|
||||
* 获取所有节点信息的回调处理
|
||||
|
@ -180,6 +180,11 @@ private:
|
|||
*/
|
||||
void setEndPointToCache(bool bInactive);
|
||||
|
||||
/*
|
||||
* 更新外部地址
|
||||
*/
|
||||
virtual void onUpdateOutter() {};
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
|
@ -251,7 +256,7 @@ protected:
|
|||
*/
|
||||
bool _rootServant;
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
/////////以下是请求主控的策略信息/////////////////
|
||||
|
||||
|
@ -327,7 +332,7 @@ public:
|
|||
/*
|
||||
* 构造函数
|
||||
*/
|
||||
EndpointManager(ObjectProxy* pObjectProxy, Communicator* pComm, const string & sObjName, bool bFirstNetThread, const string& setName = "");
|
||||
EndpointManager(ObjectProxy* pObjectProxy, Communicator* pComm, bool bFirstNetThread);
|
||||
|
||||
/*
|
||||
* 析构函数
|
||||
|
@ -346,7 +351,14 @@ public:
|
|||
*/
|
||||
void updateEndpoints(const set<EndpointInfo> & active, const set<EndpointInfo> & inactive);
|
||||
|
||||
/*
|
||||
/**
|
||||
* 外部其他通信过来的更新
|
||||
* @param active
|
||||
* @param inactive
|
||||
*/
|
||||
void updateEndpointsOutter(const set<EndpointInfo> & active, const set<EndpointInfo> & inactive);
|
||||
|
||||
/*
|
||||
* 重写基类的实现
|
||||
*/
|
||||
void doNotify();
|
||||
|
@ -365,6 +377,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
virtual void onUpdateOutter();
|
||||
|
||||
/*
|
||||
* 轮询选取一个结点
|
||||
|
@ -535,6 +548,15 @@ private:
|
|||
* 一致性hash普通使用
|
||||
*/
|
||||
TC_ConsistentHashNew _consistentHash;
|
||||
|
||||
struct OutterUpdate
|
||||
{
|
||||
set<EndpointInfo> active;
|
||||
set<EndpointInfo> inactive;
|
||||
};
|
||||
|
||||
shared_ptr<OutterUpdate> _outterUpdate;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -598,9 +620,7 @@ private:
|
|||
/*
|
||||
* 锁
|
||||
*/
|
||||
// TC_ThreadLock _mutex;
|
||||
TC_SpinLock _mutex;
|
||||
|
||||
TC_ThreadMutex _mutex;
|
||||
|
||||
/*
|
||||
* 活跃的结点
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "util/tc_common.h"
|
||||
#include "util/tc_logger.h"
|
||||
#include "util/tc_thread_mutex.h"
|
||||
#include "util/tc_coroutine.h"
|
||||
#include "tup/RequestF.h"
|
||||
#include "servant/BaseF.h"
|
||||
|
||||
|
@ -40,7 +41,7 @@ namespace tars
|
|||
{
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
const size_t MAX_CLIENT_THREAD_NUM = 64; //客户端最大网络线程数
|
||||
const size_t MAX_CLIENT_THREAD_NUM = 2048; //客户端最大网络线程数(线程模型: 网络线程数, 协程模型: 业务线程+网络线程)
|
||||
const size_t MAX_CLIENT_ASYNCTHREAD_NUM = 1024; //客户端每个网络线程拥有的最大异步线程数
|
||||
const size_t MAX_CLIENT_NOTIFYEVENT_NUM = 2048; //客户端每个网络线程拥有的最大通知事件的数目
|
||||
|
||||
|
@ -52,11 +53,10 @@ class ServantProxyCallback;
|
|||
class ObjectProxy;
|
||||
class Current;
|
||||
class FDReactor;
|
||||
class Transceiver;
|
||||
class TC_Transceiver;
|
||||
class StatFProxy;
|
||||
class StatReport;
|
||||
class ServantProxyFactory;
|
||||
class ObjectProxyFactory;
|
||||
class AsyncProcThread;
|
||||
class LocalRollLogger;
|
||||
class RemoteConfig;
|
||||
|
@ -98,58 +98,14 @@ struct TarsException : public TC_Exception
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// 定义网络异常
|
||||
/**
|
||||
* 建立连接异常
|
||||
*/
|
||||
struct TarsNetConnectException : public TarsException
|
||||
{
|
||||
TarsNetConnectException(const string &buffer) : TarsException(buffer){};
|
||||
TarsNetConnectException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsNetConnectException() throw(){};
|
||||
};
|
||||
/**
|
||||
* 链接丢失
|
||||
*/
|
||||
struct TarsNetConnectLostException : public TarsException
|
||||
{
|
||||
TarsNetConnectLostException(const string &buffer) : TarsException(buffer){};
|
||||
TarsNetConnectLostException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsNetConnectLostException() throw(){};
|
||||
};
|
||||
/**
|
||||
* Socket异常
|
||||
*/
|
||||
struct TarsNetSocketException : public TarsException
|
||||
{
|
||||
TarsNetSocketException(const string &buffer) : TarsException(buffer){};
|
||||
TarsNetSocketException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsNetSocketException() throw(){};
|
||||
};
|
||||
/**
|
||||
* Proxy解码异常
|
||||
*/
|
||||
struct TarsProxyDecodeException : public TarsException
|
||||
{
|
||||
TarsProxyDecodeException(const string &buffer) : TarsException(buffer){};
|
||||
TarsProxyDecodeException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsProxyDecodeException() throw(){};
|
||||
};
|
||||
/**
|
||||
* Proxy编码异常
|
||||
*/
|
||||
struct TarsProxyEncodeException : public TarsException
|
||||
{
|
||||
TarsProxyEncodeException(const string &buffer) : TarsException(buffer){};
|
||||
TarsProxyEncodeException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsProxyEncodeException() throw(){};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Server编码异常
|
||||
*/
|
||||
struct TarsServerEncodeException : public TarsException
|
||||
{
|
||||
TarsServerEncodeException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerEncodeException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerEncodeException() throw(){};
|
||||
};
|
||||
/**
|
||||
|
@ -158,25 +114,24 @@ struct TarsServerEncodeException : public TarsException
|
|||
struct TarsServerDecodeException : public TarsException
|
||||
{
|
||||
TarsServerDecodeException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerDecodeException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerDecodeException() throw(){};
|
||||
};
|
||||
|
||||
/**
|
||||
* Server无函数异常
|
||||
*/
|
||||
struct TarsServerNoFuncException : public TarsException
|
||||
{
|
||||
TarsServerNoFuncException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerNoFuncException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerNoFuncException() throw(){};
|
||||
};
|
||||
|
||||
/**
|
||||
* Server无对象异常
|
||||
*/
|
||||
struct TarsServerNoServantException : public TarsException
|
||||
{
|
||||
TarsServerNoServantException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerNoServantException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerNoServantException() throw(){};
|
||||
};
|
||||
/**
|
||||
|
@ -185,43 +140,60 @@ struct TarsServerNoServantException : public TarsException
|
|||
struct TarsServerQueueTimeoutException : public TarsException
|
||||
{
|
||||
TarsServerQueueTimeoutException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerQueueTimeoutException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerQueueTimeoutException() throw(){};
|
||||
};
|
||||
/**
|
||||
* 连接异常
|
||||
*/
|
||||
struct TarsServerConnectionException : public TarsException
|
||||
{
|
||||
TarsServerConnectionException(const string &buffer) : TarsException(buffer){};
|
||||
~TarsServerConnectionException() throw(){};
|
||||
};
|
||||
/**
|
||||
* 调用超时(连接都没有成功建立)
|
||||
*/
|
||||
struct TarsServerInvokeTimeoutException : public TarsException
|
||||
{
|
||||
TarsServerInvokeTimeoutException(const string &buffer) : TarsException(buffer){};
|
||||
~TarsServerInvokeTimeoutException() throw(){};
|
||||
};
|
||||
/**
|
||||
* 服务端返回的未知值
|
||||
*/
|
||||
struct TarsServerUnknownException : public TarsException
|
||||
{
|
||||
TarsServerUnknownException(const string &buffer) : TarsException(buffer){};
|
||||
TarsServerUnknownException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsServerUnknownException() throw(){};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 同步调用超时异常
|
||||
*/
|
||||
struct TarsSyncCallTimeoutException : public TarsException
|
||||
{
|
||||
TarsSyncCallTimeoutException (const string &buffer) : TarsException(buffer){};
|
||||
TarsSyncCallTimeoutException (const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsSyncCallTimeoutException () throw(){};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 访问 Registry 错误
|
||||
*/
|
||||
struct TarsRegistryException : public TarsException
|
||||
{
|
||||
TarsRegistryException(const string &buffer) : TarsException(buffer){};
|
||||
TarsRegistryException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsRegistryException() throw(){};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 客户端队列满了
|
||||
*/
|
||||
struct TarsClientQueueException : public TarsException
|
||||
{
|
||||
TarsClientQueueException(const string &buffer) : TarsException(buffer){};
|
||||
TarsClientQueueException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsClientQueueException() throw(){};
|
||||
};
|
||||
|
||||
|
@ -231,9 +203,17 @@ struct TarsClientQueueException : public TarsException
|
|||
struct TarsUseCoroException : public TarsException
|
||||
{
|
||||
TarsUseCoroException(const string &buffer) : TarsException(buffer){};
|
||||
TarsUseCoroException(const string &buffer, int err) : TarsException(buffer, err){};
|
||||
~TarsUseCoroException() throw(){};
|
||||
};
|
||||
|
||||
/**
|
||||
* 通信器析构了
|
||||
*/
|
||||
struct TarsCommunicatorException : public TarsException
|
||||
{
|
||||
TarsCommunicatorException(const string &buffer) : TarsException(buffer){};
|
||||
~TarsCommunicatorException() throw(){};
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,13 +21,11 @@
|
|||
#include "util/tc_autoptr.h"
|
||||
#include "util/tc_monitor.h"
|
||||
#include "util/tc_loop_queue.h"
|
||||
#include "servant/CoroutineScheduler.h"
|
||||
#include "servant/Global.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class CoroutineScheduler;
|
||||
/**
|
||||
|
||||
* 超时一定比率后进行切换
|
||||
|
@ -52,7 +50,7 @@ struct CheckTimeoutInfo
|
|||
CheckTimeoutInfo()
|
||||
: minTimeoutInvoke(2)
|
||||
, checkTimeoutInterval(60)
|
||||
, frequenceFailInvoke(5)
|
||||
, frequenceFailInvoke(2)
|
||||
, minFrequenceFailTime(5)
|
||||
, radio(0.5)
|
||||
, tryTimeInterval(10)
|
||||
|
@ -96,18 +94,45 @@ struct CheckTimeoutInfo
|
|||
uint32_t maxConnectExc;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 用于同步调用时的条件变量
|
||||
*/
|
||||
struct ReqMonitor : public TC_ThreadLock
|
||||
{
|
||||
};
|
||||
|
||||
#define IS_MSG_TYPE(m, t) ((m & t) != 0)
|
||||
#define SET_MSG_TYPE(m, t) do { (m |= t); } while (0);
|
||||
#define CLR_MSG_TYPE(m, t) do { (m &=~t); } while (0);
|
||||
|
||||
struct ThreadPrivateData
|
||||
{
|
||||
/**
|
||||
* hash属性,客户端每次调用都进行设置
|
||||
*/
|
||||
bool _hash = false; //是否普通取模hash
|
||||
bool _conHash = false; //是否一致性hash
|
||||
int64_t _hashCode = -1; //hash值
|
||||
|
||||
/**
|
||||
* 染色信息
|
||||
*/
|
||||
bool _dyeing = false; //标识当前线程是否需要染色
|
||||
string _dyeingKey; //染色的key值
|
||||
|
||||
/**
|
||||
* 允许客户端设置接口级别的超时时间,包括同步和异步、单向
|
||||
*/
|
||||
int _timeout = 0; //超时时间
|
||||
|
||||
/**
|
||||
* 保存调用后端服务的地址信息
|
||||
*/
|
||||
string _szHost; //调用对端地址
|
||||
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
map<string, string> _cookie; // cookie内容
|
||||
|
||||
};
|
||||
|
||||
struct ReqMonitor;
|
||||
|
||||
struct ReqMessage : public TC_HandleBase
|
||||
{
|
||||
//调用类型
|
||||
|
@ -116,7 +141,7 @@ struct ReqMessage : public TC_HandleBase
|
|||
SYNC_CALL = 1, //同步
|
||||
ASYNC_CALL, //异步
|
||||
ONE_WAY, //单向
|
||||
THREAD_EXIT //线程退出的标识
|
||||
// THREAD_EXIT //线程退出的标识
|
||||
};
|
||||
|
||||
//请求状态
|
||||
|
@ -129,120 +154,80 @@ struct ReqMessage : public TC_HandleBase
|
|||
|
||||
};
|
||||
|
||||
/*
|
||||
* 构造函数
|
||||
*/
|
||||
ReqMessage()
|
||||
: eStatus(ReqMessage::REQ_REQ)
|
||||
, eType(SYNC_CALL)
|
||||
, bFromRpc(false)
|
||||
, callback(NULL)
|
||||
, proxy(NULL)
|
||||
, pObjectProxy(NULL)
|
||||
, pMonitor(NULL)
|
||||
, bMonitorFin(false)
|
||||
, iBeginTime(0)
|
||||
, iEndTime(0)
|
||||
, bHash(false)
|
||||
, bConHash(false)
|
||||
, iHashCode(0)
|
||||
, adapter(NULL)
|
||||
, bDyeing(false)
|
||||
, bPush(false)
|
||||
, bCoroFlag(false)
|
||||
, sched(NULL)
|
||||
, iCoroId(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* 构造函数
|
||||
*/
|
||||
ReqMessage()
|
||||
: eStatus(ReqMessage::REQ_REQ)
|
||||
, eType(SYNC_CALL)
|
||||
, bFromRpc(false)
|
||||
, callback(NULL)
|
||||
, proxy(NULL)
|
||||
, pObjectProxy(NULL)
|
||||
, adapter(NULL)
|
||||
, pMonitor(NULL)
|
||||
, iBeginTime(TNOWMS)
|
||||
, iEndTime(0)
|
||||
, bPush(false)
|
||||
, sched(NULL)
|
||||
, iCoroId(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* 析构函数
|
||||
*/
|
||||
~ReqMessage()
|
||||
{
|
||||
if(deconstructor)
|
||||
{
|
||||
deconstructor();
|
||||
}
|
||||
|
||||
if(pMonitor != NULL)
|
||||
{
|
||||
delete pMonitor;
|
||||
pMonitor = NULL;
|
||||
}
|
||||
}
|
||||
~ReqMessage();
|
||||
|
||||
/*
|
||||
* 初始化
|
||||
*/
|
||||
void init(CallType eCallType)
|
||||
{
|
||||
eStatus = ReqMessage::REQ_REQ;
|
||||
eType = eCallType;
|
||||
bFromRpc = false;
|
||||
|
||||
callback = NULL;
|
||||
proxy = NULL;
|
||||
pObjectProxy = NULL;
|
||||
|
||||
response = std::make_shared<ResponsePacket>();
|
||||
sReqData = std::make_shared<TC_NetWorkBuffer::Buffer>();
|
||||
pMonitor = NULL;
|
||||
bMonitorFin = false;
|
||||
|
||||
iBeginTime = 0;
|
||||
iEndTime = 0;
|
||||
bHash = false;
|
||||
bConHash = false;
|
||||
iHashCode = 0;
|
||||
adapter = NULL;
|
||||
|
||||
bDyeing = false;
|
||||
|
||||
bPush = false;
|
||||
|
||||
bCoroFlag = false;
|
||||
sched = NULL;
|
||||
iCoroId = 0;
|
||||
}
|
||||
void init(CallType eCallType, ServantProxy *proxy);
|
||||
|
||||
ReqStatus eStatus; //调用的状态
|
||||
CallType eType; //调用类型
|
||||
bool bFromRpc; //是否是第三方协议的rcp_call,缺省为false
|
||||
ServantProxyCallbackPtr callback; //异步调用时的回调对象
|
||||
|
||||
ServantProxy * proxy; //调用的ServantProxy对象
|
||||
ObjectProxy * pObjectProxy; //调用端的proxy对象
|
||||
|
||||
bool bFromRpc = false; //是否是第三方协议的rcp_call,缺省为false
|
||||
RequestPacket request; //请求消息体
|
||||
std::function<void()> deconstructor; //析构时调用
|
||||
shared_ptr<ResponsePacket> response; //响应消息体
|
||||
// string sReqData; //请求消息体
|
||||
shared_ptr<ResponsePacket> response; //响应消息体
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> sReqData; //请求消息体
|
||||
ServantProxyCallbackPtr callback; //异步调用时的回调对象
|
||||
ServantProxy *proxy = NULL;
|
||||
ObjectProxy *pObjectProxy = NULL; //调用端的proxy对象
|
||||
AdapterProxy *adapter = NULL; //调用的adapter
|
||||
|
||||
ReqMonitor *pMonitor; //用于同步的monitor
|
||||
volatile bool bMonitorFin; //同步请求timewait是否结束
|
||||
int64_t iBeginTime; //请求时间
|
||||
int64_t iEndTime; //完成时间
|
||||
bool bHash; //是否hash调用
|
||||
bool bConHash; //是否一致性hash调用
|
||||
int64_t iHashCode; //hash值,用户保证一个用户的请求发送到同一个server(不严格保证)
|
||||
AdapterProxy *adapter; //调用的adapter
|
||||
ReqMonitor *pMonitor = NULL; //用于同步的monitor
|
||||
|
||||
bool bDyeing; //是否需要染色
|
||||
string sDyeingKey; //染色key
|
||||
int64_t iBeginTime = 0; //请求时间
|
||||
int64_t iEndTime = 0; //完成时间
|
||||
|
||||
bool bPush; //push back 消息
|
||||
bool bPush = false; //push back 消息
|
||||
|
||||
bool bCoroFlag;
|
||||
bool bTraceCall; // 是否需要调用链追踪
|
||||
string sTraceKey; // 调用链key
|
||||
|
||||
CoroutineScheduler *sched;
|
||||
shared_ptr<TC_CoroutineScheduler> sched;
|
||||
int iCoroId = 0;
|
||||
|
||||
uint32_t iCoroId;
|
||||
std::function<void()> deconstructor; //析构时调用
|
||||
|
||||
map<string, string> cookie; // cookie内容
|
||||
ThreadPrivateData data; //线程数据
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, std::string> trackInfoMap; //调用链信息
|
||||
/**
|
||||
* 用于同步调用时的条件变量
|
||||
*/
|
||||
struct ReqMonitor
|
||||
{
|
||||
ReqMessage *msg = NULL;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
bool bMonitorFin = false; //同步请求timewait是否结束
|
||||
|
||||
ReqMonitor(ReqMessage *m) : msg(m) {}
|
||||
|
||||
void wait();
|
||||
void notify();
|
||||
};
|
||||
|
||||
typedef TC_AutoPtr<ReqMessage> ReqMessagePtr;
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __TARS_NETWORK_UTIL_H_
|
||||
#define __TARS_NETWORK_UTIL_H_
|
||||
|
||||
#include "util/tc_socket.h"
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
#include <WS2tcpip.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
struct NetworkUtil
|
||||
{
|
||||
static int createSocket(bool udp, bool isLocal = false, bool isIpv6 = false);
|
||||
static void closeSocketNoThrow(int);
|
||||
static bool doConnect(int, const struct sockaddr *, socklen_t len);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -32,19 +32,7 @@ namespace tars
|
|||
class EndpointManager;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* socket选项
|
||||
*/
|
||||
struct SocketOpt
|
||||
{
|
||||
int level;
|
||||
|
||||
int optname;
|
||||
|
||||
const void *optval;
|
||||
|
||||
SOCKET_LEN_TYPE optlen;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -60,13 +48,18 @@ public:
|
|||
* @param sObjectProxyName
|
||||
* @param setName 指定set调用的setid
|
||||
*/
|
||||
ObjectProxy(CommunicatorEpoll * pCommunicatorEpoll, const string & sObjectProxyName, const string& setName="");
|
||||
ObjectProxy(CommunicatorEpoll * pCommunicatorEpoll, ServantProxy *servantProxy, const string & sObjectProxyName, const string& setName="");
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
~ObjectProxy();
|
||||
|
||||
/**
|
||||
* initialize
|
||||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
* 加载locator
|
||||
*/
|
||||
|
@ -91,38 +84,6 @@ public:
|
|||
*/
|
||||
void onNotifyEndpoints(const set<EndpointInfo> & active,const set<EndpointInfo> & inactive);
|
||||
|
||||
/**
|
||||
* 设置协议解析器
|
||||
* @return UserProtocol&
|
||||
*/
|
||||
void setProxyProtocol(const ProxyProtocol& protocol);
|
||||
|
||||
/**
|
||||
* 获取协议解析器
|
||||
* @return ProxyProtocol&
|
||||
*/
|
||||
ProxyProtocol& getProxyProtocol();
|
||||
|
||||
/**
|
||||
*设置套接口选项
|
||||
*/
|
||||
void setSocketOpt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen);
|
||||
|
||||
/**
|
||||
* 获取套接字选项
|
||||
*/
|
||||
vector<SocketOpt>& getSocketOpt();
|
||||
|
||||
/**
|
||||
* 设置PUSH类消息的callback对象
|
||||
* @param cb
|
||||
*/
|
||||
void setPushCallbacks(const ServantProxyCallbackPtr& cb);
|
||||
|
||||
/**
|
||||
* 获取PUSH类消息的callback对象
|
||||
*/
|
||||
ServantProxyCallbackPtr getPushCallback();
|
||||
|
||||
/**
|
||||
* connected
|
||||
|
@ -142,105 +103,53 @@ public:
|
|||
/**
|
||||
* 获取CommunicatorEpoll*
|
||||
*/
|
||||
inline CommunicatorEpoll * getCommunicatorEpoll()
|
||||
{
|
||||
return _communicatorEpoll;
|
||||
}
|
||||
inline CommunicatorEpoll *getCommunicatorEpoll() { return _communicatorEpoll; }
|
||||
|
||||
/**
|
||||
* 获取object名称
|
||||
* @return const string&
|
||||
*/
|
||||
inline const string & name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
inline const string & name() const { return _name; }
|
||||
|
||||
/**
|
||||
* address
|
||||
* @return
|
||||
*/
|
||||
inline const string &hash() const
|
||||
{
|
||||
return _hash;
|
||||
}
|
||||
inline const string &hash() const { return _hash; }
|
||||
|
||||
/**
|
||||
* address
|
||||
* @return
|
||||
*/
|
||||
inline const string &address() const
|
||||
{
|
||||
return _address;
|
||||
}
|
||||
inline const string &address() const { return _address; }
|
||||
|
||||
/**
|
||||
* reconnect
|
||||
* @param second
|
||||
*/
|
||||
inline void reconnect(int second)
|
||||
{
|
||||
_reConnectSecond = second;
|
||||
}
|
||||
inline void reconnect(int second) { _reConnectSecond = second; }
|
||||
|
||||
/**
|
||||
* reconnect
|
||||
* @param second
|
||||
*/
|
||||
inline int reconnect()
|
||||
{
|
||||
return _reConnectSecond;
|
||||
}
|
||||
inline int reconnect() { return _reConnectSecond; }
|
||||
|
||||
/**
|
||||
* 判断此obj是否走按set规则调用流程,如果是直连方式,即使服务端是启用set的,也不认为是按set规则调用的
|
||||
*/
|
||||
bool isInvokeBySet() const
|
||||
{
|
||||
return _isInvokeBySet;
|
||||
}
|
||||
inline bool isInvokeBySet() const { return _isInvokeBySet; }
|
||||
|
||||
/**
|
||||
* 获取按set规则调用的set名称
|
||||
*/
|
||||
const string& getInvokeSetName() const
|
||||
{
|
||||
return _invokeSetId;
|
||||
}
|
||||
inline const string& getInvokeSetName() const { return _invokeSetId; }
|
||||
|
||||
/**
|
||||
* 获取连接超时时间
|
||||
* @return int
|
||||
*/
|
||||
inline int getConTimeout()
|
||||
{
|
||||
return _conTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接超时时间
|
||||
*/
|
||||
inline void setConTimeout(int conTimeout)
|
||||
{
|
||||
_conTimeout = conTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 超时策略获取和设置
|
||||
* @return CheckTimeoutInfo&
|
||||
*/
|
||||
inline CheckTimeoutInfo& checkTimeoutInfo()
|
||||
{
|
||||
return _checkTimeoutInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取servantproxy
|
||||
*/
|
||||
inline ServantProxy * getServantProxy()
|
||||
{
|
||||
return _servantProxy;
|
||||
}
|
||||
inline ServantProxy * getServantProxy() { return _servantProxy; }
|
||||
|
||||
/**
|
||||
* 获取servantproxy
|
||||
|
@ -254,21 +163,13 @@ public:
|
|||
return _servantProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置servantproxy
|
||||
*/
|
||||
inline void setServantProxy(ServantProxy * pServantProxy)
|
||||
{
|
||||
_servantProxy = pServantProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
inline EndpointManager* getEndpointManager()
|
||||
inline const shared_ptr<EndpointManager> &getEndpointManager()
|
||||
{
|
||||
return _endpointManger.get();
|
||||
return _endpointManger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,11 +184,6 @@ public:
|
|||
*/
|
||||
void onSetInactive(const EndpointInfo& ep);
|
||||
|
||||
/**
|
||||
* 完成一个包的调用(正常返回或者超时)
|
||||
* @param ep
|
||||
*/
|
||||
void finishInvoke(ReqMessage * msg, AdapterProxy *adapterProxy);
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -297,11 +193,13 @@ protected:
|
|||
void doInvokeException(ReqMessage * msg);
|
||||
|
||||
void prepareConnection(AdapterProxy *adapterProxy);
|
||||
|
||||
friend class AdapterProxy;
|
||||
private:
|
||||
/*
|
||||
* 客户端网络线程的指针
|
||||
*/
|
||||
CommunicatorEpoll * _communicatorEpoll;
|
||||
CommunicatorEpoll *_communicatorEpoll;
|
||||
|
||||
/*
|
||||
* [obname]#hash@tcp -h xxxx -p xxx
|
||||
|
@ -335,46 +233,17 @@ private:
|
|||
*/
|
||||
bool _isInvokeBySet;
|
||||
|
||||
/*
|
||||
* 是否调用了taf_set_protocol设置过proxy的协议函数,
|
||||
* 设置过了就不在设置
|
||||
*/
|
||||
bool _hasSetProtocol;
|
||||
|
||||
/*
|
||||
* 请求和响应的协议解析器
|
||||
*/
|
||||
ProxyProtocol _proxyProtocol;
|
||||
|
||||
/*
|
||||
* 连接超时的时间
|
||||
*/
|
||||
int _conTimeout;
|
||||
|
||||
/**
|
||||
* reconnect, 0: not reconnect
|
||||
*/
|
||||
int _reConnectSecond = 0;
|
||||
|
||||
/*
|
||||
* 超时控制策略信息
|
||||
*/
|
||||
CheckTimeoutInfo _checkTimeoutInfo;
|
||||
|
||||
/*
|
||||
* socket选项
|
||||
*/
|
||||
vector<SocketOpt> _socketOpts;
|
||||
|
||||
/*
|
||||
* push消息 callback
|
||||
*/
|
||||
ServantProxyCallbackPtr _pushCallback;
|
||||
|
||||
/*
|
||||
* 结点路由管理类
|
||||
*/
|
||||
std::unique_ptr<EndpointManager> _endpointManger;
|
||||
std::shared_ptr<EndpointManager> _endpointManger;
|
||||
|
||||
/*
|
||||
* 超时队列(连接建立前)
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
//
|
||||
// Created by jarod on 2020/4/7.
|
||||
//
|
||||
|
||||
#ifndef TARS_CPP_PROXYINFO_H
|
||||
#define TARS_CPP_PROXYINFO_H
|
||||
|
||||
#include "util/tc_clientsocket.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class ProxyBase
|
||||
{
|
||||
public:
|
||||
ProxyBase(const TC_Endpoint & ep, const string & user, const string & pass)
|
||||
: _stage(eProxy_Stage_Establish), _ep(ep), _user(user), _pass(pass)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ProxyBase() {}
|
||||
|
||||
enum EMProxyStageType
|
||||
{
|
||||
eProxy_Stage_Establish,
|
||||
eProxy_Stage_ACK1,
|
||||
eProxy_Stage_ACK2,
|
||||
eProxy_Stage_Connected,
|
||||
eProxy_Stage_DisConn,
|
||||
};
|
||||
|
||||
typedef std::function<void(EMProxyStageType)> ProxyStageChangedCallback;
|
||||
|
||||
const TC_Endpoint & getEndpoint() const { return _ep; }
|
||||
|
||||
virtual bool sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst) = 0;
|
||||
|
||||
virtual bool recvProxyPacket(const char *buff, size_t length) = 0;
|
||||
|
||||
bool isSuccess() { return _stage == eProxy_Stage_Connected; }
|
||||
|
||||
void reset() { _stage = eProxy_Stage_Establish; }
|
||||
protected:
|
||||
void onDisconnect();
|
||||
void onConnSuccess();
|
||||
void setProxyStage(EMProxyStageType proxyStage);
|
||||
|
||||
protected:
|
||||
EMProxyStageType _stage;
|
||||
TC_Endpoint _ep;
|
||||
std::string _user;
|
||||
std::string _pass;
|
||||
};
|
||||
|
||||
class ProxySock4 : public ProxyBase
|
||||
{
|
||||
public:
|
||||
ProxySock4(const TC_Endpoint & ep)
|
||||
: ProxyBase(ep, "", "")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
static const int kProxy_Sock4_Req1_VN = 4;
|
||||
static const int kProxy_Sock4_Req1_CD = 1;
|
||||
|
||||
static const int kProxy_Sock4_Ans1_VN = 0;
|
||||
static const int kProxy_Sock4_Ans1_CD = 90;
|
||||
|
||||
struct sock4req1
|
||||
{
|
||||
char VN;
|
||||
char CD;
|
||||
char DSTPORT[2];
|
||||
char DSTIP[4];
|
||||
char USERID[1];
|
||||
};
|
||||
|
||||
struct sock4ans1
|
||||
{
|
||||
char VN;
|
||||
char CD;
|
||||
char DSTPORT[2];
|
||||
char DSTIP[4];
|
||||
};
|
||||
|
||||
public:
|
||||
virtual bool sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst);
|
||||
|
||||
virtual bool recvProxyPacket(const char *buff, size_t length);
|
||||
};
|
||||
|
||||
class ProxySock5 : public ProxyBase
|
||||
{
|
||||
public:
|
||||
ProxySock5(const TC_Endpoint & ep, const string & user, const string & pass)
|
||||
: ProxyBase(ep, user, pass)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
static const int kProxy_Sock5_Req1_Ver = 5;
|
||||
static const int kProxy_Sock5_Req1_nMethods = 2;
|
||||
static const int kProxy_Sock5_Req1_nMethods0 = 0; //NO AUTHENTICATION REQUIRED
|
||||
static const int kProxy_Sock5_Req1_nMethods1 = 2; //USERNAME/PASSWORD
|
||||
|
||||
static const int kProxy_Sock5_Req3_Ver = 5;
|
||||
static const int kProxy_Sock5_Req3_Cmd = 1;
|
||||
static const int kProxy_Sock5_Req3_Rsv = 0;
|
||||
static const int kProxy_Sock5_Req3_AtypIpv4 = 1;
|
||||
static const int kProxy_Sock5_Req3_AtypDns = 3;
|
||||
static const int kProxy_Sock5_Req3_AtypIpv6 = 4;
|
||||
|
||||
static const int kProxy_Sock5_Ans1_Ver = 5;
|
||||
static const int kProxy_Sock5_Ans1_Method_Anonymous = 0;
|
||||
static const int kProxy_Sock5_Ans1_Method_User = 2;
|
||||
|
||||
static const int kProxy_Sock5_Anthans_Ver = 1;
|
||||
static const int kProxy_Sock5_Anthans_Status = 0;
|
||||
|
||||
static const int kProxy_Sock5_Ans2_Ver = 5;
|
||||
static const int kProxy_Sock5_Ans2_Rep = 0;
|
||||
|
||||
static const int kProxy_IP_Length = 4;
|
||||
static const int kProxy_PORT_Length = 2;
|
||||
|
||||
struct sock5req1
|
||||
{
|
||||
char Ver;
|
||||
char nMethods;
|
||||
char Methods[2];
|
||||
//char Methods[255];
|
||||
};
|
||||
|
||||
struct sock5ans1
|
||||
{
|
||||
char Ver;
|
||||
char Method;
|
||||
};
|
||||
|
||||
struct sock5req2
|
||||
{
|
||||
char Ver;
|
||||
char Cmd;
|
||||
char Rsv;
|
||||
char Atyp;
|
||||
//char other[1];
|
||||
char DSTADDR[4];
|
||||
char DSTPORT[2];
|
||||
};
|
||||
|
||||
struct sock5ans2
|
||||
{
|
||||
char Ver;
|
||||
char Rep;
|
||||
char Rsv;
|
||||
char Atyp;
|
||||
char DSTADDR[4];
|
||||
char DSTPORT[2];
|
||||
};
|
||||
|
||||
struct authans
|
||||
{
|
||||
char Ver;
|
||||
char Status;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual bool sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst);
|
||||
|
||||
virtual bool recvProxyPacket(const char *buff, size_t length);
|
||||
|
||||
};
|
||||
|
||||
class ProxyHttp : public ProxyBase
|
||||
{
|
||||
public:
|
||||
ProxyHttp(const TC_Endpoint & ep, const string & user, const string & pass)
|
||||
: ProxyBase(ep, user, pass)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst);
|
||||
|
||||
virtual bool recvProxyPacket(const char *buff, size_t length);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //TAF_CPP_PROXYINFO_H
|
|
@ -17,12 +17,15 @@
|
|||
#ifndef __TARS_LOGGER_H__
|
||||
#define __TARS_LOGGER_H__
|
||||
|
||||
#include "util/tc_logger.h"
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_singleton.h"
|
||||
#include "servant/Global.h"
|
||||
#include "servant/LogF.h"
|
||||
#include "servant/PropertyReport.h"
|
||||
#include "util/tc_base64.h"
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_logger.h"
|
||||
#include "util/tc_platform.h"
|
||||
#include "util/tc_thread_rwlock.h"
|
||||
#include "util/tc_singleton.h"
|
||||
|
||||
#define DYEING_DIR "tars_dyeing"
|
||||
#define DYEING_FILE "dyeing"
|
||||
|
@ -64,14 +67,13 @@ public:
|
|||
|
||||
void operator()(ostream &of, const deque<pair<size_t, string> > &ds);
|
||||
|
||||
void setDyeingLogInfo(const string &sApp, const string &sServer, const string & sLogPath,
|
||||
int iMaxSize, int iMaxNum, const CommunicatorPtr &comm, const string & sLogObj);
|
||||
void setDyeingLogInfo(const string &sApp, const string &sServer, const string & sLogPath, int iMaxSize, int iMaxNum, const LogPrx &logPrx, const string & sLogObj);
|
||||
|
||||
protected:
|
||||
|
||||
TC_RollLogger *_dyeingRollLogger;
|
||||
|
||||
static int _dyeingThread;
|
||||
// static int _dyeingThread;
|
||||
|
||||
string _app;
|
||||
string _server;
|
||||
|
@ -84,7 +86,6 @@ protected:
|
|||
*/
|
||||
LogPrx _logPrx;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -105,9 +106,14 @@ public:
|
|||
DEBUG_LOG = 5, /**写错误,警告,调试log*/
|
||||
TARS_LOG = 6 /**写错误,警告,调试,Info log*/
|
||||
};
|
||||
public:
|
||||
|
||||
typedef TC_Logger<RollWriteT, TC_RollBySize> RollLogger;
|
||||
|
||||
/**
|
||||
* 析构
|
||||
*/
|
||||
~LocalRollLogger();
|
||||
|
||||
/**
|
||||
* 设置本地信息
|
||||
* @param app, 业务名称
|
||||
|
@ -132,6 +138,13 @@ public:
|
|||
*/
|
||||
RollLogger *logger() { return &_logger; }
|
||||
|
||||
/**
|
||||
* 获取循环日志, 以suffix为文件名后缀
|
||||
*
|
||||
* @return RollLogger
|
||||
*/
|
||||
RollLogger *logger(const string &suffix);
|
||||
|
||||
/**
|
||||
* 染色日志是否启用
|
||||
* @param bEnable
|
||||
|
@ -159,16 +172,39 @@ public:
|
|||
*/
|
||||
string _logpath;
|
||||
|
||||
/**
|
||||
* log obj
|
||||
*/
|
||||
string _logObj;
|
||||
|
||||
/**
|
||||
* 循环日志
|
||||
*/
|
||||
RollLogger _logger;
|
||||
|
||||
/**
|
||||
* 扩展日志
|
||||
*/
|
||||
unordered_map<string, RollLogger*> _logger_ex;
|
||||
|
||||
/**
|
||||
* lock
|
||||
*/
|
||||
TC_ThreadRWLocker _mutex;
|
||||
|
||||
/**
|
||||
* 本地线程组
|
||||
*/
|
||||
TC_LoggerThreadGroup _local;
|
||||
|
||||
/**
|
||||
* 染色远程滚动日志代理
|
||||
*/
|
||||
LogPrx _logPrx;
|
||||
|
||||
/**
|
||||
* 是否结束
|
||||
*/
|
||||
bool _terminate = false;
|
||||
};
|
||||
|
||||
|
@ -788,21 +824,7 @@ public:
|
|||
/**
|
||||
* 析构函数,关闭已打开的染色日志
|
||||
*/
|
||||
~TarsDyeingSwitch()
|
||||
{
|
||||
if(_needDyeing)
|
||||
{
|
||||
LocalRollLogger::getInstance()->enableDyeing(false);
|
||||
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
if (td)
|
||||
{
|
||||
td->_dyeing = false;
|
||||
td->_dyeingKey = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
~TarsDyeingSwitch();
|
||||
|
||||
/**
|
||||
* 获取染色的key
|
||||
|
@ -810,37 +832,12 @@ public:
|
|||
* @param key
|
||||
* @return bool
|
||||
*/
|
||||
static bool getDyeingKey(string & sDyeingkey)
|
||||
{
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
|
||||
if (td && td->_dyeing == true)
|
||||
{
|
||||
sDyeingkey = td->_dyeingKey;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool getDyeingKey(string & sDyeingkey);
|
||||
|
||||
/**
|
||||
* 启用染色日志
|
||||
*/
|
||||
void enableDyeing(const string & sDyeingKey = "")
|
||||
{
|
||||
LocalRollLogger::getInstance()->enableDyeing(true);
|
||||
|
||||
ServantProxyThreadData * td = ServantProxyThreadData::getData();
|
||||
assert(NULL != td);
|
||||
if(td)
|
||||
|
||||
{
|
||||
td->_dyeing = true;
|
||||
td->_dyeingKey = sDyeingKey;
|
||||
}
|
||||
_needDyeing = true;
|
||||
_dyeingKey = sDyeingKey;
|
||||
}
|
||||
void enableDyeing(const string & sDyeingKey = "");
|
||||
|
||||
protected:
|
||||
bool _needDyeing;
|
||||
|
@ -855,6 +852,11 @@ protected:
|
|||
#define LOG_DEBUG LOG->debug() << FILE_FUNC_LINE << "|"
|
||||
#define LOG_ERROR LOG->error() << FILE_FUNC_LINE << "|"
|
||||
|
||||
#define LOG_EX(x) (LocalRollLogger::getInstance()->logger(x))
|
||||
|
||||
#define LOG_DEBUG_EX(x) LOG_EX(x)->debug() << FILE_FUNC_LINE << "|"
|
||||
#define LOG_ERROR_EX(x) LOG_EX(x)->error() << FILE_FUNC_LINE << "|"
|
||||
|
||||
/**
|
||||
* @brief 按级别循环日志宏
|
||||
*
|
||||
|
@ -878,6 +880,20 @@ protected:
|
|||
if (LOG->isNeedLog(level)) \
|
||||
LOG->log(level) << FILE_FUNC_LINE << "|" << __VA_ARGS__; \
|
||||
} while (0)
|
||||
|
||||
#define LOGEXMSG(x, level, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (x->isNeedLog(level)) \
|
||||
x->log(level) << __VA_ARGS__; \
|
||||
} while (0)
|
||||
#define LOGEX_MSG(x, level, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (x->isNeedLog(level)) \
|
||||
x->log(level) << FILE_FUNC_LINE << "|" << __VA_ARGS__; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define LOGMSG(level, msg...) \
|
||||
do \
|
||||
|
@ -891,6 +907,20 @@ protected:
|
|||
if (LOG->isNeedLog(level)) \
|
||||
LOG->log(level) << FILE_FUNC_LINE << "|" << msg; \
|
||||
} while (0)
|
||||
|
||||
#define LOGEXMSG(x, level, msg...) \
|
||||
do \
|
||||
{ \
|
||||
if (x->isNeedLog(level)) \
|
||||
x->log(level) << msg; \
|
||||
} while (0)
|
||||
#define LOGEX_MSG(x, level, msg...) \
|
||||
do \
|
||||
{ \
|
||||
if (x->isNeedLog(level)) \
|
||||
x->log(level) << FILE_FUNC_LINE << "|" << msg; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -903,27 +933,52 @@ protected:
|
|||
* 框架宏方式: TLOGINFO("I have " << vApple.size() << " apples!"<<endl);
|
||||
*/
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
#define TLOGTARS(...) LOGMSG(LocalRollLogger::TARS_LOG,__VA_ARGS__)
|
||||
#define TLOGINFO(...) LOGMSG(LocalRollLogger::INFO_LOG,__VA_ARGS__)
|
||||
#define TLOGDEBUG(...) LOGMSG(LocalRollLogger::DEBUG_LOG,__VA_ARGS__)
|
||||
#define TLOGWARN(...) LOGMSG(LocalRollLogger::WARN_LOG,__VA_ARGS__)
|
||||
#define TLOGERROR(...) LOGMSG(LocalRollLogger::ERROR_LOG,__VA_ARGS__)
|
||||
#define TLOGTARS(...) LOGMSG(LocalRollLogger::TARS_LOG,__VA_ARGS__)
|
||||
#define TLOG_TARS(...) LOG_MSG(LocalRollLogger::TARS_LOG,__VA_ARGS__)
|
||||
#define TLOG_INFO(...) LOG_MSG(LocalRollLogger::INFO_LOG,__VA_ARGS__)
|
||||
#define TLOG_DEBUG(...) LOG_MSG(LocalRollLogger::DEBUG_LOG,__VA_ARGS__)
|
||||
#define TLOG_WARN(...) LOG_MSG(LocalRollLogger::WARN_LOG,__VA_ARGS__)
|
||||
#define TLOG_ERROR(...) LOG_MSG(LocalRollLogger::ERROR_LOG,__VA_ARGS__)
|
||||
#define TLOG_TARS(...) LOG_MSG(LocalRollLogger::TARS_LOG,__VA_ARGS__)
|
||||
|
||||
#define TLOGEXTARS(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::TARS_LOG, __VA_ARGS__)
|
||||
#define TLOGEXTARS(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::TARS_LOG, __VA_ARGS__)
|
||||
#define TLOGEXINFO(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::INFO_LOG, __VA_ARGS__)
|
||||
#define TLOGEXDEBUG(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::DEBUG_LOG, __VA_ARGS__)
|
||||
#define TLOGEXWARN(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::WARN_LOG, __VA_ARGS__)
|
||||
#define TLOGEXERROR(x, ...) LOGEXMSG(LOG_EX(x), LocalRollLogger::ERROR_LOG, __VA_ARGS__)
|
||||
|
||||
#define TLOGEX_TARS(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::TARS_LOG, __VA_ARGS__)
|
||||
#define TLOGEX_TARS(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::TARS_LOG, __VA_ARGS__)
|
||||
#define TLOGEX_INFO(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::INFO_LOG, __VA_ARGS__)
|
||||
#define TLOGEX_DEBUG(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::DEBUG_LOG, __VA_ARGS__)
|
||||
#define TLOGEX_WARN(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::WARN_LOG, __VA_ARGS__)
|
||||
#define TLOGEX_ERROR(x, ...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::ERROR_LOG, __VA_ARGS__)
|
||||
#else
|
||||
#define TLOGTARS(msg...) LOGMSG(LocalRollLogger::TARS_LOG,msg)
|
||||
#define TLOGINFO(msg...) LOGMSG(LocalRollLogger::INFO_LOG,msg)
|
||||
#define TLOGDEBUG(msg...) LOGMSG(LocalRollLogger::DEBUG_LOG,msg)
|
||||
#define TLOGWARN(msg...) LOGMSG(LocalRollLogger::WARN_LOG,msg)
|
||||
#define TLOGERROR(msg...) LOGMSG(LocalRollLogger::ERROR_LOG,msg)
|
||||
#define TLOGTARS(msg...) LOGMSG(LocalRollLogger::TARS_LOG,msg)
|
||||
#define TLOG_TARS(msg...) LOG_MSG(LocalRollLogger::TARS_LOG,msg)
|
||||
#define TLOG_INFO(msg...) LOG_MSG(LocalRollLogger::INFO_LOG,msg)
|
||||
#define TLOG_DEBUG(msg...) LOG_MSG(LocalRollLogger::DEBUG_LOG,msg)
|
||||
#define TLOG_WARN(msg...) LOG_MSG(LocalRollLogger::WARN_LOG,msg)
|
||||
#define TLOG_ERROR(msg...) LOG_MSG(LocalRollLogger::ERROR_LOG,msg)
|
||||
#define TLOG_TARS(msg...) LOG_MSG(LocalRollLogger::TARS_LOG,msg)
|
||||
#define TLOGEXTARS(x, msg...) LOGEXMSG(LOG_EX(x), LocalRollLogger::TARS_LOG, msg)
|
||||
#define TLOGEXINFO(x, msg...) LOGEXMSG(LOG_EX(x), LocalRollLogger::INFO_LOG, msg)
|
||||
#define TLOGEXDEBUG(x, msg...) LOGEXMSG(LOG_EX(x), LocalRollLogger::DEBUG_LOG, msg)
|
||||
#define TLOGEXWARN(x, msg...) LOGEXMSG(LOG_EX(x), LocalRollLogger::WARN_LOG, msg)
|
||||
#define TLOGEXERROR(x, msg...) LOGEXMSG(LOG_EX(x), LocalRollLogger::ERROR_LOG, msg)
|
||||
|
||||
#define TLOGEX_TARS(x, msg...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::TARS_LOG, msg)
|
||||
#define TLOGEX_INFO(x, msg...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::INFO_LOG, msg)
|
||||
#define TLOGEX_DEBUG(x, msg...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::DEBUG_LOG, msg)
|
||||
#define TLOGEX_WARN(x, msg...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::WARN_LOG, msg)
|
||||
#define TLOGEX_ERROR(x, msg...) LOGEX_MSG(LOG_EX(x), LocalRollLogger::ERROR_LOG, msg)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -932,6 +987,24 @@ protected:
|
|||
#define DLOG (RemoteTimeLogger::getInstance()->logger()->any())
|
||||
#define FDLOG(x) (RemoteTimeLogger::getInstance()->logger(x)->any())
|
||||
#define FFDLOG(x,y,z) (RemoteTimeLogger::getInstance()->logger(x,y,z)->any())
|
||||
///////////////////////////////////////////
|
||||
/**
|
||||
* 调用链追踪
|
||||
*/
|
||||
#define TRACE_ANNOTATION_TS "ts"
|
||||
#define TRACE_ANNOTATION_TE "te"
|
||||
#define TRACE_ANNOTATION_CS "cs"
|
||||
#define TRACE_ANNOTATION_CR "cr"
|
||||
#define TRACE_ANNOTATION_SR "sr"
|
||||
#define TRACE_ANNOTATION_SS "ss"
|
||||
|
||||
#define TRACE_LOG_FILENAME "_t_trace_"
|
||||
// traceKey: traceType-TraceID|SpanID|ParentSpanID
|
||||
#define TARS_TRACE(traceKey, annotation, client, server, func, ret, data, ex) \
|
||||
{ \
|
||||
FDLOG(TRACE_LOG_FILENAME) << traceKey << "|" << annotation << "|" << client << "|" << server << "|" << func << "|" << TNOWMS << "|" << ret << "|" << data << "|" << ex << endl; \
|
||||
}
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 按天日志局部使能开关,针对单个日志文件进行使能,请在所有按天日志输出前调用
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
namespace tars
|
||||
{
|
||||
|
||||
class BaseNotify;
|
||||
class Application;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
#include "util/tc_epoll_server.h"
|
||||
#include "servant/Servant.h"
|
||||
#include "servant/StatReport.h"
|
||||
#include "servant/CoroutineScheduler.h"
|
||||
#ifdef TARS_OPENTRACKING
|
||||
#include "opentracing/span.h"
|
||||
#endif
|
||||
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// #include "opentracing/span.h"
|
||||
// #endif
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
@ -60,34 +60,12 @@ public:
|
|||
*/
|
||||
~ServantHandle();
|
||||
|
||||
/**
|
||||
* 线程处理方法
|
||||
*/
|
||||
virtual void run();
|
||||
|
||||
/**
|
||||
* 获取协程调度器
|
||||
* get Application
|
||||
* @return
|
||||
*/
|
||||
CoroutineScheduler* getCoroSched() { return _coroSched; }
|
||||
|
||||
/**
|
||||
* get Application
|
||||
* @return
|
||||
*/
|
||||
Application *getApplication() { return _application; }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 处理接收请求的协程函数
|
||||
*/
|
||||
virtual void handleRequest();
|
||||
|
||||
/**
|
||||
* 处理请求的协程函数
|
||||
*/
|
||||
virtual void handleRecvData(const shared_ptr<TC_EpollServer::RecvContext> &data);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 线程初始化
|
||||
|
@ -118,7 +96,6 @@ protected:
|
|||
*/
|
||||
virtual void handleClose(const shared_ptr<TC_EpollServer::RecvContext> &data);
|
||||
|
||||
|
||||
/**
|
||||
* handleFilter拆分的第一部分,处理异步调用队列
|
||||
*/
|
||||
|
@ -146,7 +123,6 @@ protected:
|
|||
* @param stRecvData
|
||||
* @return Current*
|
||||
*/
|
||||
// CurrentPtr createCurrent(const TC_EpollServer::RecvContext &stRecvData);
|
||||
CurrentPtr createCurrent(const shared_ptr<TC_EpollServer::RecvContext> &data);
|
||||
|
||||
/**
|
||||
|
@ -161,27 +137,27 @@ protected:
|
|||
*
|
||||
* @param current
|
||||
*/
|
||||
void handleTarsProtocol(const TarsCurrentPtr ¤t);
|
||||
void handleTarsProtocol(const CurrentPtr ¤t);
|
||||
|
||||
/**
|
||||
* 处理非Tars协议
|
||||
*
|
||||
* @param current
|
||||
*/
|
||||
void handleNoTarsProtocol(const TarsCurrentPtr ¤t);
|
||||
void handleNoTarsProtocol(const CurrentPtr ¤t);
|
||||
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
/**
|
||||
* 处理TARS下的调用链逻辑
|
||||
*
|
||||
* @param current
|
||||
*/
|
||||
void processTracking(const TarsCurrentPtr ¤t);
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// /**
|
||||
// * 处理TARS下的调用链逻辑
|
||||
// *
|
||||
// * @param current
|
||||
// */
|
||||
// void processTracking(const CurrentPtr ¤t);
|
||||
|
||||
|
||||
void finishTracking(int ret, const TarsCurrentPtr ¤t);
|
||||
#endif
|
||||
// void finishTracking(int ret, const CurrentPtr ¤t);
|
||||
// #endif
|
||||
/**
|
||||
* 处理TARS下的染色逻辑
|
||||
*
|
||||
|
@ -189,6 +165,13 @@ protected:
|
|||
*/
|
||||
bool processDye(const CurrentPtr ¤t, string& dyeingKey);
|
||||
|
||||
/**
|
||||
* 处理TARS下的调用链追踪
|
||||
*
|
||||
* @param current
|
||||
*/
|
||||
bool processTrace(const CurrentPtr ¤t);
|
||||
|
||||
/**
|
||||
* 处理cookie
|
||||
*/
|
||||
|
@ -213,14 +196,9 @@ protected:
|
|||
unordered_map<string, ServantPtr> _servants;
|
||||
|
||||
|
||||
/**
|
||||
* 协程调度器
|
||||
*/
|
||||
CoroutineScheduler *_coroSched;
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
map<int,std::unique_ptr<opentracing::Span>> _spanMap;
|
||||
#endif
|
||||
// #ifdef TARS_OPENTRACKING
|
||||
// map<int,std::unique_ptr<opentracing::Span>> _spanMap;
|
||||
// #endif
|
||||
};
|
||||
|
||||
typedef TC_AutoPtr<ServantHandle> ServantHandlePtr;
|
||||
|
|
|
@ -49,6 +49,7 @@ struct ServantCreation : public ServantHelperCreation
|
|||
ServantPtr create(const string &s) { T *p = new T; p->setName(s); p->setApplication(_application); return p; }
|
||||
Application *_application;
|
||||
};
|
||||
|
||||
/**
|
||||
* Servant
|
||||
*/
|
||||
|
@ -66,7 +67,7 @@ struct ServantCreationWithParams : public ServantHelperCreation
|
|||
/**
|
||||
* Servant管理
|
||||
*/
|
||||
class SVT_DLL_API ServantHelperManager
|
||||
class SVT_DLL_API ServantHelperManager// : public TC_Singleton<ServantHelperManager>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -87,8 +88,8 @@ public:
|
|||
{
|
||||
if(check && _servant_adapter.end() == _servant_adapter.find(id))
|
||||
{
|
||||
cerr<<"[TARS]ServantHelperManager::addServant "<< id <<" not find adapter.(maybe not conf in the web)"<<endl;
|
||||
throw runtime_error("[TARS]ServantHelperManager::addServant " + id + " not find adapter.(maybe not conf in the web)");
|
||||
cerr<<"[ServantHelperManager::addServant "<< id <<" not find adapter.(maybe not set conf in the web)]"<<endl;
|
||||
throw runtime_error("[ServantHelperManager::addServant " + id + " not find adapter.(maybe not set conf in the web)]");
|
||||
}
|
||||
_servant_creator[id] = new ServantCreation<T>(application);
|
||||
}
|
||||
|
@ -103,8 +104,8 @@ public:
|
|||
{
|
||||
if(check && _servant_adapter.end() == _servant_adapter.find(id))
|
||||
{
|
||||
cerr<<"[TAF]ServantHelperManager::addServant "<< id <<" not find adapter.(maybe not conf in the web)"<<endl;
|
||||
throw runtime_error("[TAF]ServantHelperManager::addServant " + id + " not find adapter.(maybe not conf in the web)");
|
||||
cerr<<"[TARS]ServantHelperManager::addServant "<< id <<" not find adapter.(maybe not conf in the web)"<<endl;
|
||||
throw runtime_error("[TARS]ServantHelperManager::addServant " + id + " not find adapter.(maybe not conf in the web)");
|
||||
}
|
||||
_servant_creator[id] = new ServantCreationWithParams<T, P>(application, p);
|
||||
}
|
||||
|
@ -147,6 +148,7 @@ public:
|
|||
*/
|
||||
const string &getServantAdapter(const string& sServant) const
|
||||
{
|
||||
|
||||
static const string s = "";
|
||||
|
||||
auto it = _servant_adapter.find(sServant);
|
||||
|
|
|
@ -17,19 +17,23 @@
|
|||
#ifndef _TARS_SERVANT_PROXY_H_
|
||||
#define _TARS_SERVANT_PROXY_H_
|
||||
|
||||
#include "util/tc_common.h"
|
||||
#include "util/tc_uuid_generator.h"
|
||||
#include "util/tc_monitor.h"
|
||||
#include "util/tc_autoptr.h"
|
||||
#include "util/tc_proxy_info.h"
|
||||
#include "util/tc_singleton.h"
|
||||
#include "servant/Message.h"
|
||||
#include "servant/AppProtocol.h"
|
||||
#include "servant/Current.h"
|
||||
//#include "servant/EndpointInfo.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/EndpointInfo.h"
|
||||
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class CommunicatorEpoll;
|
||||
class EndpointInfo;
|
||||
class ProxyBase;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -50,6 +54,11 @@ public:
|
|||
*/
|
||||
SeqManager(uint16_t iNum);
|
||||
|
||||
/**
|
||||
* 析构
|
||||
*/
|
||||
~SeqManager();
|
||||
|
||||
/**
|
||||
* 获取seq
|
||||
*/
|
||||
|
@ -73,17 +82,49 @@ private:
|
|||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* 线程私有数据
|
||||
*/
|
||||
class ServantProxyThreadData
|
||||
class ServantProxyThreadData : public std::enable_shared_from_this<ServantProxyThreadData>
|
||||
{
|
||||
public:
|
||||
static TC_SpinLock _mutex;
|
||||
static SeqManager *_pSeq;
|
||||
/**
|
||||
* 全局不死的数据, 私用指针, 且不delete
|
||||
* 业务不需要主动使用该对象!
|
||||
*/
|
||||
class Immortal
|
||||
{
|
||||
public:
|
||||
Immortal();
|
||||
~Immortal();
|
||||
void add(ServantProxyThreadData *data);
|
||||
void erase(ServantProxyThreadData* data);
|
||||
void erase(Communicator * comm);
|
||||
unordered_set<ServantProxyThreadData *> getList();
|
||||
|
||||
SeqManager *getSeqManager() { return _pSeq.get(); }
|
||||
|
||||
protected:
|
||||
unordered_set<ServantProxyThreadData*> _sp_list;
|
||||
|
||||
TC_ThreadMutex _mutex;
|
||||
|
||||
unique_ptr<SeqManager> _pSeq;
|
||||
|
||||
};
|
||||
|
||||
static shared_ptr<Immortal> g_immortal;
|
||||
|
||||
public:
|
||||
|
||||
static thread_local shared_ptr<ServantProxyThreadData> g_sp;
|
||||
|
||||
/**
|
||||
* global Immortal ptr, 避免Immortal提前被释放掉
|
||||
*/
|
||||
shared_ptr<Immortal> _sp_immortal;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
|
@ -101,69 +142,261 @@ public:
|
|||
static ServantProxyThreadData * getData();
|
||||
|
||||
/**
|
||||
* reset
|
||||
* 析构通信器时调用
|
||||
* @param communicator
|
||||
*/
|
||||
static void reset();
|
||||
static void deconstructor(Communicator *communicator);
|
||||
|
||||
/**
|
||||
* move掉
|
||||
*/
|
||||
ThreadPrivateData move();
|
||||
|
||||
/**
|
||||
* 业务发起调用的线程和网络通信器间都有一个队列
|
||||
*/
|
||||
struct CommunicatorEpollReqQueueInfo
|
||||
{
|
||||
weak_ptr<ReqInfoQueue> _reqQueue;
|
||||
weak_ptr<CommunicatorEpoll> _communicatorEpoll;
|
||||
};
|
||||
|
||||
//每发起调用的线程 记录的 公有网络通信器数据
|
||||
//此时业务线程和
|
||||
struct CommunicatorEpollInfo
|
||||
{
|
||||
/*
|
||||
* 每个线程跟客户端网络线程通信的队列
|
||||
* <网络线程序号, 网络通信信息>
|
||||
*/
|
||||
vector<CommunicatorEpollReqQueueInfo> _info;
|
||||
size_t _netSeq = 0; //轮训选择网络线程的偏移量
|
||||
Communicator *_communicator = NULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* 业务线程处于协程模式下, 记录当前网络通信器信息
|
||||
* 此时业务线程和网络通信器是一对一的, 即用自身线程对应的私有网络通信器即可
|
||||
*/
|
||||
struct SchedCommunicatorEpollInfo
|
||||
{
|
||||
CommunicatorEpollReqQueueInfo _info;
|
||||
Communicator *_communicator = NULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化当前业务线程和网络通信器之间的关系(构建发送队列)
|
||||
*/
|
||||
shared_ptr<ServantProxyThreadData::CommunicatorEpollInfo> addCommunicatorEpoll(const shared_ptr<CommunicatorEpoll> &ce);
|
||||
|
||||
/**
|
||||
* 通信器析构时调用
|
||||
* @param communicator
|
||||
*/
|
||||
void erase(Communicator *communicator);
|
||||
|
||||
/**
|
||||
* 获取公有通信器对应的网络通信器等基本信息
|
||||
* @param communicator
|
||||
* @return
|
||||
*/
|
||||
shared_ptr<CommunicatorEpollInfo> getCommunicatorEpollInfo(Communicator *communicator);
|
||||
|
||||
/**
|
||||
* 获取私有通信器对应的网络通信器等基本信息
|
||||
* @param communicator
|
||||
* @return
|
||||
*/
|
||||
shared_ptr<SchedCommunicatorEpollInfo> getSchedCommunicatorEpollInfo(Communicator *communicator);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* communicator对应的公用网路通信器
|
||||
*/
|
||||
unordered_map<Communicator*, shared_ptr<CommunicatorEpollInfo>> _communicatorEpollInfo;
|
||||
|
||||
/**
|
||||
* 私有的网络通信器, 每个业务线程都对应一个, 业务线程是协程模式下使用
|
||||
*/
|
||||
unordered_map<Communicator*, shared_ptr<SchedCommunicatorEpollInfo>> _schedCommunicatorEpollInfo;
|
||||
|
||||
public:
|
||||
/*
|
||||
* 每个线程跟客户端网络线程通信的队列
|
||||
*/
|
||||
ReqInfoQueue * _reqQueue[MAX_CLIENT_THREAD_NUM]; //队列数组
|
||||
bool _queueInit; //是否初始化
|
||||
uint16_t _reqQNo; //请求事件通知的seq
|
||||
size_t _netSeq; //轮训选择网络线程的偏移量
|
||||
int _netThreadSeq; //网络线程发起的请求回到自己的网络线程来处理,其值为网络线程的id
|
||||
//lock
|
||||
TC_ThreadMutex _mutex;
|
||||
|
||||
/**
|
||||
* hash属性,客户端每次调用都进行设置
|
||||
*/
|
||||
bool _hash; //是否普通取模hash
|
||||
bool _conHash; //是否一致性hash
|
||||
int64_t _hashCode; //hash值
|
||||
|
||||
/**
|
||||
* 染色信息
|
||||
*/
|
||||
bool _dyeing; //标识当前线程是否需要染色
|
||||
string _dyeingKey; //染色的key值
|
||||
|
||||
/**
|
||||
* 允许客户端设置接口级别的超时时间,包括同步和异步、单向
|
||||
*/
|
||||
bool _hasTimeout; //是否设置超时间
|
||||
int _timeout; //超时时间
|
||||
|
||||
/**
|
||||
* 保存调用后端服务的地址信息
|
||||
*/
|
||||
string _szHost; //调用对端地址
|
||||
//业务线程的序号, 通知网络线程时, 知道用哪个notify来唤醒网路线程
|
||||
uint16_t _reqQNo;
|
||||
|
||||
/**
|
||||
* 协程调度
|
||||
*/
|
||||
CoroutineScheduler* _sched; //协程调度器
|
||||
shared_ptr<TC_CoroutineScheduler> _sched;
|
||||
|
||||
/**
|
||||
* 线程私有数据
|
||||
*/
|
||||
ThreadPrivateData _data;
|
||||
|
||||
/**
|
||||
* 当前线程是否关联了网络通信器, 如果关联了, 则表示当前线程处于网络线程中!
|
||||
*/
|
||||
CommunicatorEpoll *_communicatorEpoll = NULL;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* ObjectProxy
|
||||
* 调用链追踪信息
|
||||
*/
|
||||
size_t _objectProxyNum; //ObjectProxy对象的个数,其个数由客户端的网络线程数决定,每个网络线程有一个ObjectProxy
|
||||
struct TraceContext
|
||||
{
|
||||
int traceType; // 0 不用打参数, 1 只打客户端调用参数, 2 客户端服务端参数都打印
|
||||
string traceID; // traceID
|
||||
string spanID; // spanID
|
||||
string parentSpanID; // 父spanID
|
||||
|
||||
/**
|
||||
* objectProxy Pointer
|
||||
*/
|
||||
shared_ptr<ObjectProxy *> _objectProxyOwn; //保存ObjectProxy对象的指针数组
|
||||
enum E_SpanType
|
||||
{
|
||||
EST_CS = 1,
|
||||
EST_CR = 2,
|
||||
EST_SR = 4,
|
||||
EST_SS = 8,
|
||||
EST_TS,
|
||||
EST_TE,
|
||||
};
|
||||
|
||||
// key 分两种情况,1.rpc调用; 2.异步回调
|
||||
bool init(const string& k)
|
||||
{
|
||||
vector<string> vs = TC_Common::sepstr<string>(k, "|");
|
||||
if (vs.size() == 2)
|
||||
{
|
||||
traceID = vs[0];
|
||||
parentSpanID = vs[1];
|
||||
spanID = "";
|
||||
traceType =initType(traceID);
|
||||
return true;
|
||||
}
|
||||
else if (vs.size() == 3)
|
||||
{
|
||||
traceID = vs[0];
|
||||
spanID = vs[1];
|
||||
parentSpanID = vs[2];
|
||||
traceType = initType(traceID);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cookie
|
||||
*/
|
||||
map<string, string> _cookie; // cookie内容
|
||||
static int initType(const string& tid)
|
||||
{
|
||||
string::size_type pos = tid.find("-");
|
||||
int type = 0;
|
||||
if (pos != string::npos)
|
||||
{
|
||||
type = strtol(tid.substr(0, pos).c_str(), NULL, 16);
|
||||
}
|
||||
if (type < 0 || type > 15)
|
||||
{
|
||||
type = 0;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
traceID = "";
|
||||
spanID = "";
|
||||
parentSpanID = "";
|
||||
traceType = 0;
|
||||
}
|
||||
|
||||
TraceContext()
|
||||
{
|
||||
}
|
||||
TraceContext(const string& k)
|
||||
{
|
||||
init(k);
|
||||
}
|
||||
|
||||
void newSpan()
|
||||
{
|
||||
spanID = TC_UUIDGenerator::getInstance()->genID();
|
||||
}
|
||||
|
||||
string getKey(E_SpanType es) const
|
||||
{
|
||||
switch (es)
|
||||
{
|
||||
case EST_CS:
|
||||
case EST_CR:
|
||||
case EST_TS:
|
||||
case EST_TE:
|
||||
return traceID + "|" + spanID + "|" + parentSpanID;
|
||||
break;
|
||||
case EST_SR:
|
||||
case EST_SS:
|
||||
return traceID + "|" + parentSpanID + "|*";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
string getKey(bool full) const
|
||||
{
|
||||
return full ? (traceID + "|" + spanID + "|" + parentSpanID) : (traceID + "|" + spanID);
|
||||
}
|
||||
|
||||
static bool needParam(E_SpanType es, int type)
|
||||
{
|
||||
if (es == EST_TS)
|
||||
{
|
||||
es = EST_CS;
|
||||
}
|
||||
else if (es == EST_TE)
|
||||
{
|
||||
es = EST_CR;
|
||||
}
|
||||
return (bool)((int)es & type);
|
||||
}
|
||||
};
|
||||
|
||||
bool _traceCall; //标识当前线程是否需要调用链追踪
|
||||
TraceContext _traceContext; //调用链追踪信息
|
||||
|
||||
string getTraceKey(TraceContext::E_SpanType es) const
|
||||
{
|
||||
return _traceContext.getKey(es);
|
||||
}
|
||||
string getTraceKey(bool full = false) const
|
||||
{
|
||||
return _traceContext.getKey(full);
|
||||
}
|
||||
void newSpan()
|
||||
{
|
||||
_traceContext.newSpan();
|
||||
}
|
||||
bool initTrace(const string& k)
|
||||
{
|
||||
return _traceContext.init(k);
|
||||
}
|
||||
int getTraceType() const
|
||||
{
|
||||
return _traceContext.traceType;
|
||||
}
|
||||
bool needTraceParam(TraceContext::E_SpanType es)
|
||||
{
|
||||
return _traceContext.needParam(es, _traceContext.traceType);
|
||||
}
|
||||
static bool needTraceParam(TraceContext::E_SpanType es, const string& k)
|
||||
{
|
||||
int type = TraceContext::initType(k);
|
||||
return TraceContext::needParam(es, type);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////调用链追踪 end/////
|
||||
|
||||
#ifdef TARS_OPENTRACKING
|
||||
std::unordered_map<std::string, std::string> _trackInfoMap;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -171,7 +404,7 @@ public:
|
|||
// 协程并行请求的基类
|
||||
class CoroParallelBase : virtual public TC_HandleBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
|
@ -230,27 +463,27 @@ protected:
|
|||
/**
|
||||
* 并行请求的数目
|
||||
*/
|
||||
int _num;
|
||||
int _num;
|
||||
|
||||
/**
|
||||
* 并行请求的响应还未回来的数目
|
||||
*/
|
||||
std::atomic<int> _count;
|
||||
std::atomic<int> _count;
|
||||
|
||||
/**
|
||||
* 并行请求的已发送的数目
|
||||
*/
|
||||
std::atomic<int> _req_count;
|
||||
std::atomic<int> _req_count;
|
||||
|
||||
/**
|
||||
* 互斥锁
|
||||
*/
|
||||
TC_SpinLock _mutex;
|
||||
TC_SpinLock _mutex;
|
||||
|
||||
/**
|
||||
* 请求的响应的容器
|
||||
*/
|
||||
vector<ReqMessage*> _vReqMessage;
|
||||
vector<ReqMessage*> _vReqMessage;
|
||||
};
|
||||
typedef TC_AutoPtr<CoroParallelBase> CoroParallelBasePtr;
|
||||
|
||||
|
@ -302,7 +535,7 @@ public:
|
|||
|
||||
/**
|
||||
* 异步请求是否在网络线程处理
|
||||
* taf内部用的到 业务不能设置这个值
|
||||
* 内部用的到 业务不能设置这个值
|
||||
* */
|
||||
inline void setNetThreadProcess(bool bNetThreadProcess)
|
||||
{
|
||||
|
@ -333,15 +566,15 @@ protected:
|
|||
/**
|
||||
* 连接关闭掉了(push callback 才有效),老版本的onClose不带ep,为了兼容并且带上ep
|
||||
*/
|
||||
virtual void onClose(){};
|
||||
virtual void onClose(const TC_Endpoint &ep) { onClose(); };
|
||||
virtual void onClose() {};
|
||||
virtual void onClose(const TC_Endpoint& ep) {onClose();};
|
||||
|
||||
/**
|
||||
* 连接已建立(push callback 才有效)
|
||||
*/
|
||||
virtual void onConnect(const TC_Endpoint &ep){};
|
||||
virtual void onConnect(const TC_Endpoint& ep) {};
|
||||
|
||||
friend class Transceiver;
|
||||
friend class AdapterProxy;
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -431,8 +664,22 @@ public:
|
|||
|
||||
static string STATUS_SETNAME_VALUE; //set调用
|
||||
|
||||
static string STATUS_TRACK_KEY; //track信息
|
||||
static string STATUS_TRACE_KEY; //trace信息
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* socket选项
|
||||
*/
|
||||
struct SocketOpt
|
||||
{
|
||||
int level;
|
||||
|
||||
int optname;
|
||||
|
||||
const void *optval;
|
||||
|
||||
SOCKET_LEN_TYPE optlen;
|
||||
};
|
||||
/**
|
||||
* 缺省的同步调用超时时间
|
||||
* 超时后不保证消息不会被服务端处理
|
||||
|
@ -472,14 +719,14 @@ public:
|
|||
* 构造函数
|
||||
* @param op
|
||||
*/
|
||||
ServantProxy(Communicator * pCommunicator, ObjectProxy ** ppObjectProxy, size_t iClientThreadNum);
|
||||
ServantProxy(Communicator * pCommunicator, const string& name,const string& setName);
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
virtual ~ServantProxy();
|
||||
public:
|
||||
|
||||
public:
|
||||
/**
|
||||
* 获取Object可用服务列表 如果启用set则获取本set的,如果启用分组,只返回同分组的服务端ip
|
||||
* @return void
|
||||
|
@ -528,8 +775,6 @@ public:
|
|||
*/
|
||||
vector<TC_Endpoint> getEndpoint4All();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 获取通信器
|
||||
*
|
||||
|
@ -590,10 +835,16 @@ public:
|
|||
* 获取所属的Object名称
|
||||
* @return string
|
||||
*/
|
||||
string tars_name() const;
|
||||
const string &tars_name() const;
|
||||
|
||||
/**
|
||||
* set name
|
||||
* @return
|
||||
*/
|
||||
const string &tars_setName() const;
|
||||
|
||||
/**
|
||||
* 获取所属的Object名称#hash@address
|
||||
* 获取所属的Object名称#hash@address(即传入stringToProxy中的地址)
|
||||
* @return string
|
||||
*/
|
||||
string tars_full_name() const;
|
||||
|
@ -631,13 +882,18 @@ public:
|
|||
* get protocol
|
||||
* @return
|
||||
*/
|
||||
ProxyProtocol tars_get_protocol();
|
||||
const ProxyProtocol &tars_get_protocol() const;
|
||||
|
||||
/**
|
||||
*设置套接字选项
|
||||
*/
|
||||
void tars_set_sockopt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen);
|
||||
|
||||
/**
|
||||
* 获取套接字选项
|
||||
*/
|
||||
vector<SocketOpt> tars_get_sockopt() const;
|
||||
|
||||
/**
|
||||
* 设置超时检查参数
|
||||
*/
|
||||
|
@ -662,13 +918,9 @@ public:
|
|||
*/
|
||||
virtual ServantProxy* tars_consistent_hash(int64_t key);
|
||||
|
||||
// /**
|
||||
// * 直接同步调用
|
||||
// * @return
|
||||
// */
|
||||
// virtual ServantProxy* taf_direct();
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* 清除当前的Hash数据
|
||||
* 空函数 为了兼容以前的
|
||||
* @param key
|
||||
|
@ -729,6 +981,16 @@ public:
|
|||
*/
|
||||
virtual void tars_set_push_callback(const ServantProxyCallbackPtr& cb);
|
||||
|
||||
/**
|
||||
* 获取PUSH类消息的callback对象
|
||||
*/
|
||||
ServantProxyCallbackPtr tars_get_push_callback();
|
||||
|
||||
/**
|
||||
* 超时策略获取和设置
|
||||
* @return CheckTimeoutInfo&
|
||||
*/
|
||||
inline const CheckTimeoutInfo& tars_check_timeout_info() const { return _checkTimeoutInfo; }
|
||||
|
||||
/**
|
||||
* 普通协议同步远程调用
|
||||
|
@ -795,7 +1057,11 @@ public:
|
|||
const map<string, string>& status,
|
||||
const ServantProxyCallbackPtr& callback,
|
||||
bool bCoro = false);
|
||||
|
||||
/**
|
||||
* 获取所有objectproxy(包括子servant), 该函数主要给自动测试使用!
|
||||
* @return
|
||||
*/
|
||||
vector<ObjectProxy*> getObjectProxys();
|
||||
protected:
|
||||
/**
|
||||
* 获得可以复用的servant
|
||||
|
@ -804,16 +1070,39 @@ protected:
|
|||
ServantPrx getServantPrx(ReqMessage *msg);
|
||||
|
||||
/**
|
||||
* get proxy pointer
|
||||
* get proxy info
|
||||
*/
|
||||
inline ProxyBase *getProxyInfo()
|
||||
{
|
||||
return _proxyPointer ? _proxyPointer.get() : NULL;
|
||||
}
|
||||
inline const std::shared_ptr<TC_ProxyInfo::ProxyBaseInfo>& getProxyInfo() { return _proxyBaseInfo; }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void tars_initialize();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param prx
|
||||
* @param f
|
||||
*/
|
||||
void travelObjectProxys(ServantProxy *prx, function<void(ObjectProxy*)> f);
|
||||
|
||||
friend class ServantProxyCallback;
|
||||
friend class Transceiver;
|
||||
friend class Communicator;
|
||||
friend class Communicator;
|
||||
friend class ServantProxyFactory;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* 获取第一个ObjectProxy
|
||||
* @return
|
||||
*/
|
||||
ObjectProxy *getObjectProxy(size_t netThreadSeq = 0);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param func
|
||||
*/
|
||||
void forEachObject(std::function<void(ObjectProxy*)> func);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -835,22 +1124,27 @@ private:
|
|||
* @param pSptd
|
||||
* @return void
|
||||
*/
|
||||
void selectNetThreadInfo(ServantProxyThreadData * pSptd, ObjectProxy * & pObjProxy, ReqInfoQueue * & pReqQ);
|
||||
|
||||
void selectNetThreadInfo(ServantProxyThreadData *pSptd, ObjectProxy *&pObjProxy, shared_ptr<ReqInfoQueue> &pReqQ);
|
||||
/**
|
||||
* 检查是否需要设置染色消息
|
||||
* @param req
|
||||
*/
|
||||
void checkDye(RequestPacket& req);
|
||||
|
||||
/**
|
||||
* 检查是否需要设置调用链追踪
|
||||
* @param req
|
||||
*/
|
||||
void checkTrace(RequestPacket &req);
|
||||
|
||||
/**
|
||||
* 更新endpoint
|
||||
* @param active
|
||||
* @param inactive
|
||||
*/
|
||||
void onNotifyEndpoints(size_t netThreadSeq, const set<EndpointInfo> &active, const set<EndpointInfo> &inactive, bool fromInner);
|
||||
void onNotifyEndpoints(CommunicatorEpoll *communicatorEpoll, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive);
|
||||
|
||||
/**
|
||||
/**
|
||||
* 端口不活跃
|
||||
*/
|
||||
void onSetInactive(const EndpointInfo &ep);
|
||||
|
@ -873,14 +1167,7 @@ private:
|
|||
/**
|
||||
* 保存ObjectProxy对象的指针数组
|
||||
*/
|
||||
ObjectProxy ** _objectProxy; //保存ObjectProxy对象的指针数组
|
||||
shared_ptr<ObjectProxy *> _objectProxyOwn; //保存ObjectProxy对象的指针数组
|
||||
|
||||
/**
|
||||
* ObjectProxy对象的个数,其个数由客户端的网络线程数决定,
|
||||
* 每个网络线程有一个ObjectProxy
|
||||
*/
|
||||
size_t _objectProxyNum;
|
||||
ObjectProxy * _objectProxy; //保存ObjectProxy对象的指针数组
|
||||
|
||||
/**
|
||||
* 同步调用超时(毫秒)
|
||||
|
@ -937,10 +1224,10 @@ private:
|
|||
*/
|
||||
vector<ServantPrx> _servantList;
|
||||
|
||||
/**
|
||||
*
|
||||
/**
|
||||
* 代理的基本信息
|
||||
*/
|
||||
std::shared_ptr<ProxyBase> _proxyPointer;
|
||||
std::shared_ptr<TC_ProxyInfo::ProxyBaseInfo> _proxyBaseInfo;
|
||||
|
||||
/**
|
||||
* custom callback
|
||||
|
@ -955,7 +1242,27 @@ private:
|
|||
/**
|
||||
* 链接超时
|
||||
*/
|
||||
int _connTimeout = DEFAULT_ASYNCTIMEOUT;
|
||||
int _connTimeout = DEFAULT_ASYNCTIMEOUT;
|
||||
|
||||
/*
|
||||
* 请求和响应的协议解析器
|
||||
*/
|
||||
ProxyProtocol _proxyProtocol;
|
||||
|
||||
/*
|
||||
* push消息 callback
|
||||
*/
|
||||
ServantProxyCallbackPtr _pushCallback;
|
||||
|
||||
/*
|
||||
* 超时控制策略信息
|
||||
*/
|
||||
CheckTimeoutInfo _checkTimeoutInfo;
|
||||
|
||||
/*
|
||||
* socket选项
|
||||
*/
|
||||
vector<SocketOpt> _socketOpts;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -42,30 +42,6 @@
|
|||
namespace tars
|
||||
{
|
||||
|
||||
/**
|
||||
* 状态上报类, 上报的信息包括:
|
||||
* 1 模块间调用的信息
|
||||
* 2 业务自定义的属性统计
|
||||
*/
|
||||
struct StatSampleMsgHead
|
||||
{
|
||||
string slaveName;
|
||||
string interfaceName;
|
||||
string ip;
|
||||
bool operator <(const StatSampleMsgHead& m)const
|
||||
{
|
||||
if(slaveName != m.slaveName)
|
||||
{
|
||||
return slaveName < m.slaveName;
|
||||
}
|
||||
if(interfaceName != m.interfaceName)
|
||||
{
|
||||
return interfaceName < m.interfaceName;
|
||||
}
|
||||
return ip < m.ip;
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 状态上报类, 上报的信息包括:
|
||||
|
@ -75,10 +51,9 @@ struct StatSampleMsgHead
|
|||
class StatReport : public TC_HandleBase, public TC_Thread, public TC_ThreadLock
|
||||
{
|
||||
public:
|
||||
|
||||
typedef map<StatMicMsgHead, StatMicMsgBody> MapStatMicMsg;
|
||||
typedef map<StatPropMsgHead, StatPropMsgBody> MapStatPropMsg;
|
||||
typedef multimap<StatSampleMsgHead,StatSampleMsg> MMapStatSampleMsg;
|
||||
typedef TC_LoopQueue<MapStatMicMsg*> stat_queue;
|
||||
|
||||
const static int MAX_MASTER_NAME_LEN = 127;
|
||||
const static int MAX_MASTER_IP_LEN = 50;
|
||||
|
@ -86,8 +61,7 @@ public:
|
|||
const static int MIN_REPORT_SIZE = 500; //上报的最小大小限制
|
||||
const static int STAT_PROTOCOL_LEN = 100; //一次stat mic上报纯协议部分占用大小,用来控制udp大小防止超MTU
|
||||
const static int PROPERTY_PROTOCOL_LEN = 50; //一次property上纯报协议部分占用大小,用来控制udp大小防止超MTU
|
||||
const static int MAX_STAT_QUEUE_SIZE = 10000; //上报队列缓存大小限制
|
||||
|
||||
|
||||
enum StatResult
|
||||
{
|
||||
STAT_SUCC = 0,
|
||||
|
@ -98,7 +72,7 @@ public:
|
|||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
StatReport(size_t iEpollNum=0);
|
||||
StatReport(Communicator*);
|
||||
|
||||
/**
|
||||
* 析够函数
|
||||
|
@ -217,24 +191,13 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
void report(size_t iSeq,MapStatMicMsg * pmStatMicMsg);
|
||||
|
||||
inline bool valid() { return _statPrx ; }
|
||||
|
||||
/*
|
||||
* 获取stat代理
|
||||
*/
|
||||
StatFPrx getStatPrx() {return _statPrx; }
|
||||
|
||||
// /*
|
||||
// * 采样
|
||||
// */
|
||||
// void doSample(const string& strSlaveName,
|
||||
// const string& strInterfaceName,
|
||||
// const string& strSlaveIp,
|
||||
// map<string, string> &status);
|
||||
// /*
|
||||
// * 采样id
|
||||
// */
|
||||
// string sampleUnid();
|
||||
inline StatFPrx getStatPrx() {return _statPrx; }
|
||||
|
||||
/**
|
||||
* 增加关注时间点. 调用方式addStatInterv(5)
|
||||
|
@ -311,33 +274,18 @@ private:
|
|||
*/
|
||||
int reportPropMsg();
|
||||
|
||||
// /**
|
||||
// * 上报多维度属性信息 Prop = property
|
||||
// * @return int
|
||||
// */
|
||||
// int reportPropPlusMsg();
|
||||
|
||||
/**
|
||||
* stat 采样
|
||||
*/
|
||||
int reportSampleMsg();
|
||||
|
||||
//合并两个MicMsg
|
||||
void addMicMsg(MapStatMicMsg & old,MapStatMicMsg & add);
|
||||
|
||||
/**
|
||||
* get queue info
|
||||
* @return
|
||||
*/
|
||||
size_t getQueueSize(size_t epollIndex);
|
||||
void addMicMsg(MapStatMicMsg & old, MapStatMicMsg & add);
|
||||
|
||||
friend class CommunicatorEpoll;
|
||||
private:
|
||||
Communicator* _communicator;
|
||||
|
||||
time_t _time;
|
||||
|
||||
int _reportInterval;
|
||||
|
||||
int _reportTimeout;
|
||||
int _reportTimeout;
|
||||
|
||||
int _maxReportSize;
|
||||
|
||||
|
@ -363,8 +311,6 @@ private:
|
|||
|
||||
MapStatMicMsg _statMicMsgServer;
|
||||
|
||||
MMapStatSampleMsg _statSampleMsg;
|
||||
|
||||
vector<int> _timePoint;
|
||||
|
||||
PropertyFPrx _propertyPrx;
|
||||
|
@ -373,9 +319,6 @@ private:
|
|||
|
||||
private:
|
||||
|
||||
size_t _epollNum;
|
||||
vector<stat_queue*> _statMsg;
|
||||
|
||||
size_t _retValueNumLimit;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,413 +0,0 @@
|
|||
/**
|
||||
* Tencent is pleased to support the open source community by making Tars available.
|
||||
*
|
||||
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __TARS_TRANSCEIVER_H_
|
||||
#define __TARS_TRANSCEIVER_H_
|
||||
|
||||
#include "servant/EndpointInfo.h"
|
||||
#include "servant/NetworkUtil.h"
|
||||
#include "servant/CommunicatorEpoll.h"
|
||||
#include "servant/AuthLogic.h"
|
||||
#include <list>
|
||||
#include <util/tc_network_buffer.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class TC_OpenSSL;
|
||||
|
||||
class AdapterProxy;
|
||||
class ProxyBase;
|
||||
|
||||
/**
|
||||
* 网络传输基类,主要提供send/recv接口
|
||||
*/
|
||||
class Transceiver
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* 连接状态
|
||||
*/
|
||||
enum ConnectStatus
|
||||
{
|
||||
eUnconnected,
|
||||
eConnecting,
|
||||
eConnected,
|
||||
};
|
||||
|
||||
/*
|
||||
* 发数据的返回状态
|
||||
*/
|
||||
enum ReturnStatus
|
||||
{
|
||||
eRetError = -1, //发送错误
|
||||
eRetOk = 0, //发送成功
|
||||
eRetFull = 1, //数据发送一半, 队列满了, 等事件过来继续发送
|
||||
eRetNotSend = 2, //连接还没有ok(ssl没有握手, 没有完成鉴权, 上一个数据包还没有发送完, 没有完成代理鉴权等), 数据没有发送
|
||||
};
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param ep
|
||||
* @param fd
|
||||
*/
|
||||
Transceiver(AdapterProxy * pAdapterProxy,const EndpointInfo &ep);
|
||||
|
||||
/**
|
||||
*
|
||||
*析构函数
|
||||
*/
|
||||
virtual ~Transceiver();
|
||||
|
||||
/**
|
||||
* 是否ssl
|
||||
*/
|
||||
bool isSSL() const ;
|
||||
|
||||
/*
|
||||
* 检查连接是否超时
|
||||
*/
|
||||
void checkTimeout();
|
||||
|
||||
/**
|
||||
* 重新创建连接
|
||||
*/
|
||||
void reconnect();
|
||||
|
||||
/**
|
||||
* 创建连接,初始化
|
||||
*/
|
||||
void connect();
|
||||
|
||||
/*
|
||||
* 关闭连接
|
||||
*/
|
||||
virtual void close(bool destructor=false);
|
||||
|
||||
/*
|
||||
* 设置当前连接态
|
||||
*/
|
||||
void setConnected();
|
||||
|
||||
/*
|
||||
* 往fd里面发送数据
|
||||
* 如果fd缓冲区已满,返回错误
|
||||
* 如果数据发送一半,缓冲区满了,返回成功
|
||||
*/
|
||||
int sendRequest(const shared_ptr<TC_NetWorkBuffer::Buffer> &pData);
|
||||
|
||||
/**
|
||||
* send buffer
|
||||
* @return
|
||||
*/
|
||||
TC_NetWorkBuffer *getSendBuffer() { return &_sendBuffer; }
|
||||
|
||||
/**
|
||||
* recv buffer
|
||||
* @return
|
||||
*/
|
||||
TC_NetWorkBuffer *getRecvBuffer() { return &_recvBuffer; }
|
||||
|
||||
/*
|
||||
* 处理请求,判断Send BufferCache是否有完整的包
|
||||
* @return int
|
||||
*/
|
||||
virtual int doRequest();
|
||||
|
||||
/*
|
||||
* 处理返回,判断Recv BufferCache是否有完整的包
|
||||
* @param done
|
||||
* @return int
|
||||
*/
|
||||
virtual int doResponse() = 0;
|
||||
|
||||
/*
|
||||
* 网络发送接口
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
virtual int send(const void* buf, uint32_t len, uint32_t flag) = 0;
|
||||
|
||||
/*
|
||||
* 网络接收接口
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
virtual int recv(void* buf, uint32_t len, uint32_t flag) = 0;
|
||||
|
||||
/*
|
||||
* 获取文件描述符
|
||||
* @return int
|
||||
*/
|
||||
virtual int fd() const
|
||||
{
|
||||
return _fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* 是否有效
|
||||
*/
|
||||
bool isValid() const
|
||||
{
|
||||
return (_fd != -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取端口信息
|
||||
*/
|
||||
const EndpointInfo& getEndpointInfo() const
|
||||
{
|
||||
return _ep;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取connect所属的adapter
|
||||
*/
|
||||
AdapterProxy * getAdapterProxy()
|
||||
{
|
||||
return _adapterProxy;
|
||||
}
|
||||
|
||||
/*
|
||||
* 判断是否已经连接到服务端
|
||||
*/
|
||||
bool hasConnected()
|
||||
{
|
||||
return isValid() && (_connStatus == eConnected);
|
||||
}
|
||||
|
||||
/*
|
||||
* 判断是否正在连接
|
||||
*/
|
||||
bool isConnecting()
|
||||
{
|
||||
return isValid() && (_connStatus == eConnecting);
|
||||
}
|
||||
|
||||
/*
|
||||
* 设置连接失败
|
||||
*/
|
||||
void setConnectFailed()
|
||||
{
|
||||
_connStatus = eUnconnected;
|
||||
}
|
||||
|
||||
void finishInvoke(shared_ptr<ResponsePacket> &rsp);
|
||||
|
||||
/**
|
||||
* 设置鉴权状态
|
||||
*/
|
||||
void setAuthState(AUTH_STATE newstate) { _authState = newstate; }
|
||||
|
||||
/*
|
||||
* 获取鉴权状态
|
||||
*/
|
||||
int getAuthState() const { return _authState; }
|
||||
|
||||
/*
|
||||
* 发送鉴权数据
|
||||
*/
|
||||
bool sendAuthData(const BasicAuthInfo& );
|
||||
|
||||
protected:
|
||||
/*
|
||||
* 设置当前连接态
|
||||
*/
|
||||
void onSetConnected();
|
||||
|
||||
/**
|
||||
** 物理连接成功回调
|
||||
**/
|
||||
void onConnect();
|
||||
|
||||
/**
|
||||
** 发送打通代理请求
|
||||
**/
|
||||
void connectProxy();
|
||||
|
||||
/**
|
||||
* 检查是否代理创建成功
|
||||
* @param buff
|
||||
* @param length
|
||||
* @return <0: 失败, 0: 成功: 1: 需要验证
|
||||
*/
|
||||
int doCheckProxy(const char *buff, size_t length);
|
||||
|
||||
/**
|
||||
** 鉴权初始化请求
|
||||
**/
|
||||
void doAuthReq();
|
||||
|
||||
/*
|
||||
* AdapterProxy
|
||||
*/
|
||||
AdapterProxy * _adapterProxy;
|
||||
|
||||
/*
|
||||
* 连接的节点信息
|
||||
*/
|
||||
EndpointInfo _ep;
|
||||
|
||||
/*
|
||||
* 套接字
|
||||
*/
|
||||
int _fd;
|
||||
|
||||
/*
|
||||
* 事件注册信息
|
||||
*/
|
||||
FDInfo _fdInfo;
|
||||
|
||||
/*
|
||||
* 连接状态
|
||||
*/
|
||||
ConnectStatus _connStatus;
|
||||
|
||||
/*
|
||||
* 连接的超时时间
|
||||
*/
|
||||
int64_t _conTimeoutTime;
|
||||
|
||||
/*
|
||||
* 鉴权状态
|
||||
*/
|
||||
AUTH_STATE _authState;
|
||||
|
||||
protected:
|
||||
|
||||
std::shared_ptr<TC_OpenSSL> _openssl;
|
||||
|
||||
|
||||
/*
|
||||
* 发送buffer
|
||||
*/
|
||||
TC_NetWorkBuffer _sendBuffer;
|
||||
|
||||
/*
|
||||
* 接收buffer
|
||||
*/
|
||||
TC_NetWorkBuffer _recvBuffer;
|
||||
|
||||
/**
|
||||
* 代理
|
||||
*/
|
||||
ProxyBase* _proxyPointer = NULL;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/**
|
||||
* TCP 传输实现
|
||||
*/
|
||||
class TcpTransceiver : public Transceiver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 构造函数
|
||||
* @param ep
|
||||
* @param fd
|
||||
*/
|
||||
TcpTransceiver(AdapterProxy * pAdapterProxy, const EndpointInfo &ep);
|
||||
|
||||
/**
|
||||
* TCP 发送实现
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
virtual int send(const void* buf, uint32_t len, uint32_t flag);
|
||||
|
||||
/**
|
||||
* TCP 接收实现
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
virtual int recv(void* buf, uint32_t len, uint32_t flag);
|
||||
|
||||
/**
|
||||
* 处理返回,判断Recv BufferCache是否有完整的包
|
||||
* @param done
|
||||
* @return int, =1,表示有数据就包
|
||||
*/
|
||||
virtual int doResponse();
|
||||
};
|
||||
//////////////////////////////////////////////////////////
|
||||
/**
|
||||
* UDP 传输实现
|
||||
*/
|
||||
class UdpTransceiver : public Transceiver
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
DEFAULT_RECV_BUFFERSIZE = 64*1024 /*缺省数据接收buffer的大小*/
|
||||
};
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
UdpTransceiver(AdapterProxy * pAdapterProxy, const EndpointInfo &ep);
|
||||
|
||||
/**
|
||||
* 析构函数
|
||||
*/
|
||||
~UdpTransceiver();
|
||||
|
||||
/**
|
||||
* UDP 发送实现
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
virtual int send(const void* buf, uint32_t len, uint32_t flag);
|
||||
|
||||
/**
|
||||
* UDP 接收实现
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param flag
|
||||
* @return int
|
||||
*/
|
||||
virtual int recv(void* buf, uint32_t len, uint32_t flag);
|
||||
|
||||
/**
|
||||
* 处理返回,判断Recv BufferCache是否有完整的包
|
||||
* @param done
|
||||
* @return int
|
||||
*/
|
||||
virtual int doResponse();
|
||||
|
||||
private:
|
||||
/*
|
||||
* 接收缓存
|
||||
*/
|
||||
char* _pRecvBuffer;
|
||||
};
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
#endif
|
|
@ -21,6 +21,8 @@
|
|||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <functional>
|
||||
|
@ -28,6 +30,7 @@
|
|||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <set>
|
||||
|
||||
#if defined _WIN32 || defined _WIN64
|
||||
#pragma comment(lib,"ws2_32.lib")
|
||||
|
@ -473,18 +476,6 @@ public:
|
|||
template<typename OutputStreamT>
|
||||
void writeTo(OutputStreamT& os)
|
||||
{
|
||||
/*
|
||||
helper h;
|
||||
h.type = _type;
|
||||
if(_tag < 15){
|
||||
h.tag = _tag;
|
||||
os.writeBuf(&h, sizeof(h));
|
||||
}else{
|
||||
h.tag = 15;
|
||||
os.writeBuf(&h, sizeof(h));
|
||||
os.writeBuf(&_tag, sizeof(_tag));
|
||||
}
|
||||
*/
|
||||
writeTo(os, _type, _tag);
|
||||
}
|
||||
|
||||
|
@ -497,13 +488,13 @@ public:
|
|||
if (tag < 15)
|
||||
{
|
||||
h.tag = tag;
|
||||
os.writeBuf((const char *)&h, sizeof(h));
|
||||
os.writeBuf((const char*)&h, sizeof(h));
|
||||
}
|
||||
else
|
||||
{
|
||||
h.tag = 15;
|
||||
os.writeBuf((const char *)&h, sizeof(h));
|
||||
os.writeBuf((const char *)&tag, sizeof(tag));
|
||||
os.writeBuf((const char*)&h, sizeof(h));
|
||||
os.writeBuf((const char*)&tag, sizeof(tag));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -657,6 +648,10 @@ public:
|
|||
//指针需要内存时通过偏移指向预分配内存块,减少解码过程中的内存申请
|
||||
class MapBufferReader : public BufferReader
|
||||
{
|
||||
private:
|
||||
MapBufferReader(const MapBufferReader&);
|
||||
|
||||
MapBufferReader& operator=(const MapBufferReader&);
|
||||
|
||||
public:
|
||||
MapBufferReader() : _buf_m(NULL),_buf_len_m(0),_cur_m(0) {}
|
||||
|
@ -751,8 +746,8 @@ public:
|
|||
_len += len;
|
||||
}
|
||||
std::vector<char> getByteBuffer() const { return std::vector<char>(_buf, _buf + _len);}
|
||||
const char * getBuffer() const { return _buf;}//{ return &_buf[0]; }
|
||||
size_t getLength() const { return _len;} //{ return _buf.size(); }
|
||||
const char * getBuffer() const { return _buf;}
|
||||
size_t getLength() const { return _len;}
|
||||
void swap(std::vector<char>& v) { v.assign(_buf, _buf + _len); }
|
||||
void swap(std::string& v) { v.assign(_buf, _len); }
|
||||
void swap(BufferWriter& buf)
|
||||
|
@ -989,7 +984,7 @@ public:
|
|||
break;
|
||||
case TarsHeadeString4:
|
||||
{
|
||||
size_t len = 0;
|
||||
uint32_t len = 0;
|
||||
TarsReadTypeBuf(*this, len, uint32_t);
|
||||
len = ntohl((uint32_t)len);
|
||||
TarsReadHeadSkip(*this, len);
|
||||
|
@ -1087,6 +1082,7 @@ public:
|
|||
Char c = b;
|
||||
read(c, tag, isRequire);
|
||||
b = c ? true : false;
|
||||
if (tag) { } //avoid compiler warning
|
||||
}
|
||||
|
||||
void read(Char& c, uint8_t tag, bool isRequire = true)
|
||||
|
@ -1246,7 +1242,7 @@ public:
|
|||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'Int64' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
snprintf(s, sizeof(s), "read 'Int64' type mismatch, tag: %d, headTag: %d, get type: %d.", tag, headTag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
|
||||
|
@ -1279,7 +1275,7 @@ public:
|
|||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'Float' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
snprintf(s, sizeof(s), "read 'Float' type mismatch, tag: %d, get type: %d, headTag: %d.", tag, headType, headTag);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
|
@ -1315,7 +1311,7 @@ public:
|
|||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'Double' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
snprintf(s, sizeof(s), "read 'Double' type mismatch, tag: %d, get type: %d, headType: %d.", tag, headType,headTag);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
|
@ -1328,73 +1324,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/*void read(std::string& s, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeString1:
|
||||
{
|
||||
size_t len = 0;
|
||||
TarsReadTypeBuf(*this, len, uint8_t);
|
||||
char ss[256];
|
||||
//s.resize(len);
|
||||
//this->readBuf((void *)s.c_str(), len);
|
||||
TarsReadStringBuf(*this, s, len);
|
||||
//TarsReadBuf(*this, s, len);
|
||||
//s.assign(ss, ss + len);
|
||||
}
|
||||
break;
|
||||
case TarsHeadeString4:
|
||||
{
|
||||
uint32_t len = 0;
|
||||
TarsReadTypeBuf(*this, len, uint32_t);
|
||||
len = ntohl(len);
|
||||
if (tars_unlikely(len > TARS_MAX_STRING_LENGTH))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid string size, tag: %d, size: %d", tag, len);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
//char *ss = new char[len];
|
||||
//s.resize(len);
|
||||
//this->readBuf((void *)s.c_str(), len);
|
||||
|
||||
char *ss = new char[len];
|
||||
try
|
||||
{
|
||||
TarsReadBuf(*this, ss, len);
|
||||
s.assign(ss, ss + len);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete[] ss;
|
||||
throw;
|
||||
}
|
||||
delete[] ss;
|
||||
TarsReadStringBuf(*this, s, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'string' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}*/
|
||||
|
||||
void read(std::string& s, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
|
@ -1417,7 +1346,7 @@ public:
|
|||
if (tars_unlikely(strLength > TARS_MAX_STRING_LENGTH))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid string size, tag: %d, size: %d", tag, strLength);
|
||||
snprintf(s, sizeof(s), "invalid string size, tag: %d, size: %d, headTag: %d", tag, strLength, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
}
|
||||
|
@ -1506,7 +1435,7 @@ public:
|
|||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid map, tag: %d, size: %d", tag, size);
|
||||
snprintf(s, sizeof(s), "invalid map, tag: %d, size: %d, headTag: %d", tag, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
m.clear();
|
||||
|
@ -1536,6 +1465,152 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename K, typename V, typename H, typename Cmp, typename Alloc>
|
||||
void read(std::unordered_map<K, V, H, Cmp, Alloc>& m, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeMap:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid unordered_map, tag: %d, size: %d, headTag: %d", tag, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
m.clear();
|
||||
|
||||
for (UInt32 i = 0; i < size; ++i)
|
||||
{
|
||||
std::pair<K, V> pr;
|
||||
read(pr.first, 0);
|
||||
read(pr.second, 1);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename K, typename V, typename Cmp, typename Alloc>
|
||||
void readEx(std::map<K, V, Cmp, Alloc>& m, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch (headType)
|
||||
{
|
||||
case TarsHeadeMap:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid map, tag: %d, size: %d, headTag: %d", tag, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
m.clear();
|
||||
|
||||
for (UInt32 i = 0; i < size; ++i)
|
||||
{
|
||||
std::pair<K, V> pr;
|
||||
read(pr.first, 0);
|
||||
CV tmp(pr.second);
|
||||
read(tmp, 1);
|
||||
|
||||
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename K, typename V, typename H, typename Cmp, typename Alloc>
|
||||
void readEx(std::unordered_map<K, V, H, Cmp, Alloc>& m, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch (headType)
|
||||
{
|
||||
case TarsHeadeMap:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid map, tag: %d, size: %d, headTag: %d", tag, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
m.clear();
|
||||
|
||||
for (UInt32 i = 0; i < size; ++i)
|
||||
{
|
||||
std::pair<K, V> pr;
|
||||
read(pr.first, 0);
|
||||
CV tmp(pr.second);
|
||||
read(tmp, 1);
|
||||
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
void read(std::vector<Char, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
|
@ -1565,7 +1640,11 @@ public:
|
|||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
|
||||
this->readBuf(v, size);
|
||||
v.reserve(size);
|
||||
v.resize(size);
|
||||
|
||||
this->readBuf(v.data(), size);
|
||||
//TarsReadTypeBuf(*this, v[0], Int32);
|
||||
}
|
||||
break;
|
||||
case TarsHeadeList:
|
||||
|
@ -1617,7 +1696,7 @@ public:
|
|||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d", tag, headType, size);
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
v.reserve(size);
|
||||
|
@ -1642,6 +1721,233 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Cmp, typename Alloc>
|
||||
void read(std::set<T, Cmp, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeList:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
// v.reserve(size);
|
||||
// v.resize(size);
|
||||
for (UInt32 i = 0; i < size; ++i) {
|
||||
T t;
|
||||
read(t, 0);
|
||||
v.insert(t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'set' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename H, typename Cmp, typename Alloc>
|
||||
void read(std::unordered_set<T, H, Cmp, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeList:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
// v.reserve(size);
|
||||
// v.resize(size);
|
||||
for (UInt32 i = 0; i < size; ++i) {
|
||||
T t;
|
||||
read(t, 0);
|
||||
v.insert(t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'set' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename T, typename Cmp, typename Alloc>
|
||||
void readEx(std::set<T, Cmp, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeList:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
// v.reserve(size);
|
||||
// v.resize(size);
|
||||
for (UInt32 i = 0; i < size; ++i) {
|
||||
T t;
|
||||
CV tmp(t);
|
||||
read(tmp, 0);
|
||||
v.insert(t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'set' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename T, typename H, typename Cmp, typename Alloc>
|
||||
void readEx(std::unordered_set<T, H, Cmp, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch(headType)
|
||||
{
|
||||
case TarsHeadeList:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
// v.reserve(size);
|
||||
// v.resize(size);
|
||||
for (UInt32 i = 0; i < size; ++i) {
|
||||
T t;
|
||||
CV tmp(t);
|
||||
read(tmp, 0);
|
||||
v.insert(t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'set' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename T, typename Alloc>
|
||||
void readEx(std::vector<T, Alloc>& v, uint8_t tag, bool isRequire = true)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
switch (headType)
|
||||
{
|
||||
case TarsHeadeList:
|
||||
{
|
||||
UInt32 size = 0;
|
||||
read(size, 0);
|
||||
if (tars_unlikely(size > this->size()))
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d, headTag: %d", tag, headType, size, headTag);
|
||||
throw TarsDecodeInvalidValue(s);
|
||||
}
|
||||
v.reserve(size);
|
||||
v.resize(size);
|
||||
for (UInt32 i = 0; i < size; ++i)
|
||||
{
|
||||
CV tmp(v[i]);
|
||||
read(tmp, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'vector' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// 读取结构数组
|
||||
template<typename T>
|
||||
void read(T* v, const UInt32 len, UInt32 & readLen, uint8_t tag, bool isRequire = true)
|
||||
|
@ -1692,6 +1998,34 @@ public:
|
|||
v = (T) n;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void read(T&& v, uint8_t tag, bool isRequire = true, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
uint8_t headType = 0, headTag = 0;
|
||||
bool skipFlag = false;
|
||||
TarsSkipToTag(skipFlag, tag, headType, headTag);
|
||||
if (tars_likely(skipFlag))
|
||||
{
|
||||
if (tars_unlikely(headType != TarsHeadeStructBegin))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'struct' type mismatch, tag: %d, get type: %d, headTag: %d.", tag, headType, headTag);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
|
||||
// 精度保存恢复都在 readFrom 里面做
|
||||
v.readFrom(*this);
|
||||
|
||||
skipToStructEnd();
|
||||
}
|
||||
else if (tars_unlikely(isRequire))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
|
||||
throw TarsDecodeRequireNotExist(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// 读取结构
|
||||
template<typename T>
|
||||
void read(T& v, uint8_t tag, bool isRequire = true, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
|
@ -1704,7 +2038,7 @@ public:
|
|||
if (tars_unlikely(headType != TarsHeadeStructBegin))
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "read 'struct' type mismatch, tag: %d, get type: %d.", tag, headType);
|
||||
snprintf(s, sizeof(s), "read 'struct' type mismatch, tag: %d, get type: %d, headTag: %d.", tag, headType, headTag);
|
||||
throw TarsDecodeMismatch(s);
|
||||
}
|
||||
v.readFrom(*this);
|
||||
|
@ -1741,16 +2075,6 @@ public:
|
|||
|
||||
void write(Char n, uint8_t tag)
|
||||
{
|
||||
/*
|
||||
DataHead h(DataHead::eChar, tag);
|
||||
if(n == 0){
|
||||
h.setType(DataHead::eZeroTag);
|
||||
h.writeTo(*this);
|
||||
}else{
|
||||
h.writeTo(*this);
|
||||
this->writeBuf(&n, sizeof(n));
|
||||
}
|
||||
*/
|
||||
if (tars_unlikely(n == 0))
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeZeroTag, tag);
|
||||
|
@ -1769,19 +2093,12 @@ public:
|
|||
|
||||
void write(Short n, uint8_t tag)
|
||||
{
|
||||
//if(n >= CHAR_MIN && n <= CHAR_MAX){
|
||||
if (n >= (-128) && n <= 127)
|
||||
{
|
||||
write((Char) n, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
DataHead h(DataHead::eShort, tag);
|
||||
h.writeTo(*this);
|
||||
n = htons(n);
|
||||
this->writeBuf(&n, sizeof(n));
|
||||
*/
|
||||
TarsWriteToHead(*this, TarsHeadeShort, tag);
|
||||
n = htons(n);
|
||||
TarsWriteShortTypeBuf(*this, n, (*this)._len);
|
||||
|
@ -1795,15 +2112,12 @@ public:
|
|||
|
||||
void write(Int32 n, uint8_t tag)
|
||||
{
|
||||
//if(n >= SHRT_MIN && n <= SHRT_MAX){
|
||||
if (n >= (-32768) && n <= 32767)
|
||||
{
|
||||
write((Short) n, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DataHead h(DataHead::eInt32, tag);
|
||||
//h.writeTo(*this);
|
||||
TarsWriteToHead(*this, TarsHeadeInt32, tag);
|
||||
n = htonl(n);
|
||||
TarsWriteInt32TypeBuf(*this, n, (*this)._len);
|
||||
|
@ -1817,15 +2131,12 @@ public:
|
|||
|
||||
void write(Int64 n, uint8_t tag)
|
||||
{
|
||||
//if(n >= INT_MIN && n <= INT_MAX){
|
||||
if (n >= (-2147483647-1) && n <= 2147483647)
|
||||
{
|
||||
write((Int32) n, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
//DataHead h(DataHead::eInt64, tag);
|
||||
//h.writeTo(*this);
|
||||
TarsWriteToHead(*this, TarsHeadeInt64, tag);
|
||||
n = tars_htonll(n);
|
||||
TarsWriteInt64TypeBuf(*this, n, (*this)._len);
|
||||
|
@ -1843,8 +2154,6 @@ public:
|
|||
|
||||
void write(Double n, uint8_t tag)
|
||||
{
|
||||
//DataHead h(DataHead::eDouble, tag);
|
||||
//h.writeTo(*this);
|
||||
TarsWriteToHead(*this, TarsHeadeDouble, tag);
|
||||
n = tars_htond(n);
|
||||
TarsWriteDoubleTypeBuf(*this, n, (*this)._len);
|
||||
|
@ -1863,7 +2172,7 @@ public:
|
|||
TarsWriteToHead(*this, TarsHeadeString4, tag);
|
||||
uint32_t n = htonl((uint32_t)s.size());
|
||||
TarsWriteUInt32TTypeBuf(*this, n, (*this)._len);
|
||||
//this->writeBuf(s.data(), s.size());
|
||||
|
||||
TarsWriteTypeBuf(*this, s.data(), s.size());
|
||||
}
|
||||
else
|
||||
|
@ -1871,7 +2180,7 @@ public:
|
|||
TarsWriteToHead(*this, TarsHeadeString1, tag);
|
||||
uint8_t n = (uint8_t)s.size();
|
||||
TarsWriteUInt8TTypeBuf(*this, n, (*this)._len);
|
||||
//this->writeBuf(s.data(), s.size());
|
||||
|
||||
TarsWriteTypeBuf(*this, s.data(), s.size());
|
||||
}
|
||||
}
|
||||
|
@ -1881,15 +2190,14 @@ public:
|
|||
TarsWriteToHead(*this, TarsHeadeSimpleList, tag);
|
||||
TarsWriteToHead(*this, TarsHeadeChar, 0);
|
||||
write(len, 0);
|
||||
//this->writeBuf(buf, len);
|
||||
|
||||
TarsWriteTypeBuf(*this, buf, len);
|
||||
}
|
||||
|
||||
template<typename K, typename V, typename Cmp, typename Alloc>
|
||||
void write(const std::map<K, V, Cmp, Alloc>& m, uint8_t tag)
|
||||
{
|
||||
//DataHead h(DataHead::eMap, tag);
|
||||
//h.writeTo(*this);
|
||||
|
||||
TarsWriteToHead(*this, TarsHeadeMap, tag);
|
||||
Int32 n = (Int32)m.size();
|
||||
write(n, 0);
|
||||
|
@ -1901,11 +2209,46 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<typename K, typename V, typename H, typename Cmp, typename Alloc>
|
||||
void write(const std::unordered_map<K, V, H, Cmp, Alloc>& m, uint8_t tag)
|
||||
{
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeMap, tag);
|
||||
Int32 n = (Int32)m.size();
|
||||
write(n, 0);
|
||||
typedef typename std::unordered_map<K, V, H, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
write(i->first, 0);
|
||||
write(i->second, 1);
|
||||
|
||||
std::cout << "write:" << i->first << ", " << i->second << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< typename CV, typename K, typename V, typename Cmp, typename Alloc>
|
||||
void writeEx( const std::map<K, V, Cmp, Alloc>& m, uint8_t tag)
|
||||
{
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeMap, tag);
|
||||
Int32 n = (Int32)m.size();
|
||||
write(n, 0);
|
||||
typedef typename std::map<K, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
write(i->first, 0);
|
||||
|
||||
CV cv(i->second);
|
||||
write(cv, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
void write(const std::vector<T, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
//DataHead h(DataHead::eList, tag);
|
||||
//h.writeTo(*this);
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
|
@ -1914,6 +2257,71 @@ public:
|
|||
write(*i, 0);
|
||||
}
|
||||
|
||||
template<typename T, typename Cmp, typename Alloc>
|
||||
void write(const std::set<T, Cmp, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
typedef typename std::set<T, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
write(*i, 0);
|
||||
}
|
||||
|
||||
template<typename T, typename H, typename Cmp, typename Alloc>
|
||||
void write(const std::unordered_set<T, H, Cmp, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
typedef typename std::unordered_set<T, H, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
write(*i, 0);
|
||||
}
|
||||
|
||||
template<typename CV, typename T, typename Cmp, typename Alloc>
|
||||
void writeEx(const std::set<T, Cmp, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
typedef typename std::set<T, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
CV cv(*i);
|
||||
write(cv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CV, typename T, typename H, typename Cmp, typename Alloc>
|
||||
void writeEx(const std::unordered_set<T, H, Cmp, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
typedef typename std::unordered_set<T, H, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
CV cv(*i);
|
||||
write(cv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< typename CV, typename T, typename Alloc>
|
||||
void writeEx(const std::vector<T, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
TarsWriteToHead(*this, TarsHeadeList, tag);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
typedef typename std::vector<T, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
CV cv(*i);
|
||||
write(cv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void write(const T *v, const UInt32 len, uint8_t tag)
|
||||
{
|
||||
|
@ -1928,15 +2336,12 @@ public:
|
|||
template<typename Alloc>
|
||||
void write(const std::vector<Char, Alloc>& v, uint8_t tag)
|
||||
{
|
||||
//DataHead h(DataHead::eSimpleList, tag);
|
||||
//h.writeTo(*this);
|
||||
//DataHead hh(DataHead::eChar, 0);
|
||||
//hh.writeTo(*this);
|
||||
|
||||
TarsWriteToHead(*this, TarsHeadeSimpleList, tag);
|
||||
TarsWriteToHead(*this, TarsHeadeChar, 0);
|
||||
Int32 n = (Int32)v.size();
|
||||
write(n, 0);
|
||||
//writeBuf(&v[0], v.size());
|
||||
|
||||
TarsWriteTypeBuf(*this, v.data(), v.size());
|
||||
}
|
||||
|
||||
|
@ -1949,16 +2354,10 @@ public:
|
|||
template<typename T>
|
||||
void write(const T& v, uint8_t tag, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
//DataHead h(DataHead::eStructBegin, tag);
|
||||
//h.writeTo(*this);
|
||||
|
||||
TarsWriteToHead(*this, TarsHeadeStructBegin, tag);
|
||||
v.writeTo(*this);
|
||||
TarsWriteToHead(*this, TarsHeadeStructEnd, 0);
|
||||
/*
|
||||
h.setType(DataHead::eStructEnd);
|
||||
h.setTag(0);
|
||||
h.writeTo(*this);
|
||||
*/
|
||||
}
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -399,17 +399,6 @@ public:
|
|||
void encode(string& buff)
|
||||
{
|
||||
encodeBuff<string>(buff);
|
||||
|
||||
// TarsOutputStream<TWriter> &os = UniAttribute<TWriter, TReader,Alloc>::os;
|
||||
|
||||
// os.reset();
|
||||
|
||||
// doEncode(os);
|
||||
|
||||
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
|
||||
// buff.assign((const char*)&iHeaderLen, sizeof(tars::Int32));
|
||||
|
||||
// buff.append(os.getBuffer(), os.getLength());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,18 +410,6 @@ public:
|
|||
void encode(vector<char>& buff)
|
||||
{
|
||||
encodeBuff<vector<char>>(buff);
|
||||
// TarsOutputStream<TWriter> & os = UniAttribute<TWriter, TReader,Alloc>::os;
|
||||
|
||||
// os.reset();
|
||||
|
||||
// doEncode(os);
|
||||
|
||||
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
|
||||
|
||||
// buff.resize(sizeof(tars::Int32) + os.getLength());
|
||||
// memcpy(&buff[0], &iHeaderLen, sizeof(tars::Int32));
|
||||
// memcpy(&buff[sizeof(tars::Int32)], os.getBuffer(), os.getLength());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,20 +437,6 @@ public:
|
|||
memcpy(buff + sizeof(tars::Int32), os.getBuffer(), os.getLength());
|
||||
|
||||
len = sizeof(tars::Int32) + os.getLength();
|
||||
|
||||
// TarsOutputStream<TWriter> &os = UniAttribute<TWriter, TReader,Alloc>::os;
|
||||
|
||||
// os.reset();
|
||||
|
||||
// doEncode(os);
|
||||
|
||||
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
|
||||
// if(len < sizeof(tars::Int32) + os.getLength()) throw runtime_error("encode error, buffer length too short");
|
||||
|
||||
// memcpy(buff, &iHeaderLen, sizeof(tars::Int32));
|
||||
// memcpy(buff + sizeof(tars::Int32), os.getBuffer(), os.getLength());
|
||||
|
||||
// len = sizeof(tars::Int32) + os.getLength();
|
||||
}
|
||||
|
||||
/** 解码
|
||||
|
@ -588,26 +551,6 @@ protected:
|
|||
|
||||
os.reset();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 内部编码
|
||||
// */
|
||||
// void doEncode(TarsOutputStream<TWriter>& os)
|
||||
// {
|
||||
// //ServantName、FuncName不能为空
|
||||
// if(sServantName.empty()) throw runtime_error("ServantName must not be empty");
|
||||
// if(sFuncName.empty()) throw runtime_error("FuncName must not be empty");
|
||||
|
||||
// os.reset();
|
||||
|
||||
// os.write(UniAttribute<TWriter, TReader,Alloc>::_data, 0);
|
||||
|
||||
// sBuffer.assign(os.getBuffer(), os.getBuffer() + os.getLength());
|
||||
|
||||
// os.reset();
|
||||
|
||||
// writeTo(os);
|
||||
// }
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -109,7 +109,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (option.hasParam("extends-package"))
|
||||
{
|
||||
t2a.setTafPacket(option.getValue("extends-package"));
|
||||
t2a.setTarsPacket(option.getValue("extends-package"));
|
||||
}
|
||||
|
||||
t2a.setCheckDefault(tars::TC_Common::lower(option.getValue("check-default")) == "true"?true:false);
|
||||
|
|
|
@ -88,9 +88,9 @@ public:
|
|||
void createFile(const string& file);
|
||||
|
||||
/**
|
||||
* 设置TAF库的报名
|
||||
* 设置TARS库的报名
|
||||
*/
|
||||
void setTafPacket(const std::string& sPacket)
|
||||
void setTarsPacket(const std::string& sPacket)
|
||||
{
|
||||
s_TARS_PACKAGE = sPacket + TARS_PACKAGE;
|
||||
s_PROXY_PACKAGE = sPacket + PROXY_PACKAGE;
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace tars
|
|||
* - 调度过程简单的理解就是: 检查是否有需要执行的协程, 有则执行之, 没有则等待在epoll对象上, 直到有唤醒或者超时
|
||||
* - 调度器底层使用tc_epoller来完成协程的切换, 等待和阻塞等操作, 可以和网络IO无缝粘合, 因此可以通过TC_CoroutineScheduler对象拿到TC_Epoller指针, 并用于网络IO上
|
||||
* - 由于网络IO也是用相同的epoller对象, 因此可以做到当有数据发送/接受时, 唤醒epoll对象, 从而完成协程的切换
|
||||
* - 协程启动通过: createCoroutine 函数来完成
|
||||
* - 协程启动通过: go 函数来完成
|
||||
* - 协程在运行中, 主要使用三个函数来完成, 调度控制: yield/sleep/put
|
||||
*
|
||||
* TC_Coroutine详细说明:
|
||||
|
@ -384,7 +384,7 @@ public:
|
|||
/**
|
||||
* 创建协程
|
||||
*/
|
||||
uint32_t createCoroutine(const std::function<void ()> &callback);
|
||||
uint32_t go(const std::function<void ()> &callback);
|
||||
|
||||
/**
|
||||
* 通知循环醒过来
|
||||
|
@ -706,7 +706,7 @@ public:
|
|||
* 创建协程,在已经创建的协程中使用
|
||||
* 返回值为协程的id,大于0,表示成功,,小于等于0,表示失败
|
||||
*/
|
||||
uint32_t createCoroutine(const std::function<void ()> &coroFunc);
|
||||
uint32_t go(const std::function<void ()> &coroFunc);
|
||||
|
||||
/**
|
||||
* 当前协程自己放弃执行,会自动被调度器唤醒
|
||||
|
|
|
@ -106,7 +106,7 @@ namespace detail
|
|||
virtual void info(const string &s) const = 0;
|
||||
|
||||
/**
|
||||
* taf日志
|
||||
* tars日志
|
||||
* @param s
|
||||
*/
|
||||
virtual void tars(const string &s) const = 0;
|
||||
|
@ -585,6 +585,16 @@ public:
|
|||
*/
|
||||
int sendBuffer();
|
||||
|
||||
/**
|
||||
* 直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
* send naked response data
|
||||
* @param buffer
|
||||
* @return int, -1:发送出错, 0:无数据, 1:发送完毕, 2:还有数据
|
||||
* @return int, -1: sending error, 0: no data, 1: send completely, 2: data retains
|
||||
* @return
|
||||
*/
|
||||
int sendBufferDirect(const char* buff, size_t length);
|
||||
|
||||
/**
|
||||
* 直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
* send naked response data
|
||||
|
@ -595,6 +605,16 @@ public:
|
|||
*/
|
||||
int sendBufferDirect(const std::string& buff);
|
||||
|
||||
/**
|
||||
* 直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
* send naked response data
|
||||
* @param buffer
|
||||
* @return int, -1:发送出错, 0:无数据, 1:发送完毕, 2:还有数据
|
||||
* @return int, -1: sending error, 0: no data, 1: send completely, 2: data retains
|
||||
* @return
|
||||
*/
|
||||
int sendBufferDirect(const shared_ptr<TC_NetWorkBuffer::Buffer>& buff);
|
||||
|
||||
/**
|
||||
* 添加发送buffer
|
||||
* @param buffer
|
||||
|
@ -1029,7 +1049,7 @@ public:
|
|||
const string & getProtocolName();
|
||||
|
||||
/**
|
||||
* 是否taf协议
|
||||
* 是否tars协议
|
||||
* @return bool
|
||||
*/
|
||||
bool isTarsProtocol();
|
||||
|
@ -2259,7 +2279,7 @@ public:
|
|||
virtual void info(const string &s) const;
|
||||
|
||||
/**
|
||||
* taf日志
|
||||
* tars日志
|
||||
* @param s
|
||||
*/
|
||||
virtual void tars(const string &s) const;
|
||||
|
|
|
@ -658,8 +658,8 @@ namespace tars
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief 枚举类型,定义日志的四种等级 . 此处级别被修改了,与taf标准不一样
|
||||
* @brief Enumeration type, defines four levels of logs. This level has been modified and is different from the TAF standard
|
||||
* @brief 枚举类型,定义日志的四种等级 . 此处级别被修改了,与tars标准不一样
|
||||
* @brief Enumeration type, defines four levels of logs. This level has been modified and is different from the TARS standard
|
||||
*/
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -406,13 +406,13 @@ public:
|
|||
*
|
||||
* @param sSql sql语句
|
||||
* @param sSql SQL statement
|
||||
* @param pdatafunc ,函数参数为map<string,string> ,key为column 名,value为数据
|
||||
* @param pdatafunc , Function parameter is map<string, string>, key is column name, value is data
|
||||
* @param pdatarsunc ,函数参数为map<string,string> ,key为column 名,value为数据
|
||||
* @param pdatarsunc , Function parameter is map<string, string>, key is column name, value is data
|
||||
* @throws TC_Mysql_Exception
|
||||
* @return MysqlData类型的数据,可以根据字段获取相关信息
|
||||
* @return MysqlData type of data, you can get information based on the field
|
||||
*/
|
||||
size_t travelRecord(const string& sSql, const std::function<void(const map<string,string> &)> & pdatafunc);
|
||||
size_t travelRecord(const string& sSql, const std::function<void(const map<string,string> &)> & pdatarsunc);
|
||||
|
||||
/**
|
||||
* @brief 定义字段类型,
|
||||
|
|
|
@ -1053,4 +1053,4 @@ protected:
|
|||
|
||||
}
|
||||
|
||||
#endif //TAF_CPP_TC_NETWORKBUFFER_H
|
||||
#endif //TARS_CPP_TC_NETWORKBUFFER_H
|
||||
|
|
|
@ -218,7 +218,7 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
} // end namespace taf
|
||||
} // end namespace tars
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -118,20 +118,24 @@ protected:
|
|||
|
||||
static size_t registerSig(int sig, std::function<void()> callback);
|
||||
static void unregisterSig(int sig, size_t id);
|
||||
|
||||
static void registerSig(int sig);
|
||||
|
||||
static std::mutex _mutex;
|
||||
|
||||
static unordered_map<int, unordered_map<size_t, std::function<void()>>> _callbacks;
|
||||
|
||||
static std::atomic<size_t> _callbackId;
|
||||
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
static void sighandler( int sig_no );
|
||||
static void sighandler( int sig_no );
|
||||
#else
|
||||
static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType);
|
||||
static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType);
|
||||
#endif
|
||||
|
||||
struct SigInfo
|
||||
{
|
||||
std::mutex _mutex;
|
||||
|
||||
unordered_map<int, unordered_map<size_t, std::function<void()>>> _callbacks;
|
||||
|
||||
std::atomic<size_t> _callbackId{0};
|
||||
};
|
||||
|
||||
static shared_ptr<SigInfo> _sigInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -277,4 +277,4 @@ public:
|
|||
|
||||
}
|
||||
|
||||
#endif //TAF_CPP_PROXYINFO_H
|
||||
#endif //TARS_CPP_PROXYINFO_H
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace tars
|
|||
/////////////////////////////////////////////////
|
||||
/**
|
||||
* @file tc_thread.h
|
||||
* @brief 线程类(兼容TAF4.x版本, 底层直接封装了c++11 thread, 从而跨平台兼容)
|
||||
* @brief 线程类(兼容TARS4.x版本, 底层直接封装了c++11 thread, 从而跨平台兼容)
|
||||
*
|
||||
* 使用说明:
|
||||
* - TC_Thread定义一个线程, 继承TC_Thread, 实现run方法, 调用start即可启动线程
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace tars
|
|||
/////////////////////////////////////////////////
|
||||
/**
|
||||
* @file tc_thread_cond.h
|
||||
* @brief 线程锁以及条件变量类(兼容TAF4.x版本, 底层直接封装了c++11, 从而跨平台兼容)
|
||||
* @brief 线程锁以及条件变量类(兼容TARS4.x版本, 底层直接封装了c++11, 从而跨平台兼容)
|
||||
*
|
||||
* @author jarodruan@upchina.com
|
||||
*/
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace tars
|
|||
/////////////////////////////////////////////////
|
||||
/**
|
||||
* @file tc_thread_mutex.h
|
||||
* @brief 线程锁互斥类(兼容TAF4.x版本, 底层直接封装了c++11, 从而跨平台兼容)
|
||||
* @brief 线程锁互斥类(兼容TARS4.x版本, 底层直接封装了c++11, 从而跨平台兼容)
|
||||
*
|
||||
* @author jarodruan@upchina.com
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
#include "util/tc_socket.h"
|
||||
#include "util/tc_singleton.h"
|
||||
|
||||
using namespace taf;
|
||||
namespace tars
|
||||
{
|
||||
|
||||
class TC_UUIDGenerator : public TC_Singleton<TC_UUIDGenerator>
|
||||
{
|
||||
|
@ -127,4 +128,6 @@ private:
|
|||
bool initOK;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__TC_UUID_GENERATOR_H
|
||||
|
|
|
@ -438,7 +438,7 @@ int TC_CoroutineScheduler::increaseCoroPoolSize()
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t TC_CoroutineScheduler::createCoroutine(const std::function<void ()> &callback)
|
||||
uint32_t TC_CoroutineScheduler::go(const std::function<void ()> &callback)
|
||||
{
|
||||
if(!_all_coro)
|
||||
{
|
||||
|
@ -835,7 +835,7 @@ void TC_Coroutine::handleCoro()
|
|||
//把协程创建出来
|
||||
for(uint32_t i = 0; i < _num; ++i)
|
||||
{
|
||||
_coroSched->createCoroutine(std::bind(&TC_Coroutine::coroEntry, this));
|
||||
_coroSched->go(std::bind(&TC_Coroutine::coroEntry, this));
|
||||
}
|
||||
|
||||
|
||||
|
@ -847,9 +847,9 @@ void TC_Coroutine::coroEntry(TC_Coroutine *pCoro)
|
|||
pCoro->handle();
|
||||
}
|
||||
|
||||
uint32_t TC_Coroutine::createCoroutine(const std::function<void ()> &coroFunc)
|
||||
uint32_t TC_Coroutine::go(const std::function<void ()> &coroFunc)
|
||||
{
|
||||
return _coroSched->createCoroutine(coroFunc);
|
||||
return _coroSched->go(coroFunc);
|
||||
}
|
||||
|
||||
void TC_Coroutine::yield()
|
||||
|
|
|
@ -231,7 +231,7 @@ void TC_EpollServer::Handle::handleOnceCoroutine()
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t iRet = scheduler->createCoroutine(std::bind(&Handle::handle, this, data));
|
||||
uint32_t iRet = scheduler->go(std::bind(&Handle::handle, this, data));
|
||||
if (iRet == 0)
|
||||
{
|
||||
// LOG_CONSOLE_DEBUG << "handleOverload" << endl;
|
||||
|
@ -390,7 +390,7 @@ void TC_EpollServer::Handle::handleLoopCoroutine()
|
|||
|
||||
initialize();
|
||||
|
||||
_scheduler->createCoroutine(std::bind(&Handle::handleCoroutine, this));
|
||||
_scheduler->go(std::bind(&Handle::handleCoroutine, this));
|
||||
|
||||
_epollServer->notifyThreadReady();
|
||||
|
||||
|
@ -503,7 +503,7 @@ void TC_EpollServer::Connection::initialize(TC_Epoller *epoller, unsigned int ui
|
|||
|
||||
const TC_Endpoint &ep = _pBindAdapter->getEndpoint();
|
||||
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if (ep.isSSL())
|
||||
{
|
||||
_trans.reset(new TC_SSLTransceiver(epoller, ep));
|
||||
|
@ -650,7 +650,7 @@ void TC_EpollServer::Connection::onCloseCallback(TC_Transceiver *trans, TC_Trans
|
|||
|
||||
std::shared_ptr<TC_OpenSSL> TC_EpollServer::Connection::onOpensslCallback(TC_Transceiver* trans)
|
||||
{
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if(trans->isSSL()) {
|
||||
assert(_pBindAdapter->_ctx);
|
||||
return TC_OpenSSL::newSSL(_pBindAdapter->_ctx);
|
||||
|
@ -735,46 +735,34 @@ TC_NetWorkBuffer::PACKET_TYPE TC_EpollServer::Connection::onParserCallback(TC_Ne
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int TC_EpollServer::Connection::sendBufferDirect(const std::string& buff)
|
||||
int TC_EpollServer::Connection::sendBufferDirect(const char* buff, size_t length)
|
||||
{
|
||||
_pBindAdapter->increaseSendBufferSize();
|
||||
|
||||
if(getBindAdapter()->getEndpoint().isTcp()) {
|
||||
|
||||
return _trans->sendRequest(std::make_shared<TC_NetWorkBuffer::Buffer>(buff.data(), buff.length()));
|
||||
return _trans->sendRequest(std::make_shared<TC_NetWorkBuffer::Buffer>(buff, length));
|
||||
}
|
||||
|
||||
return 0;
|
||||
//
|
||||
//#if TAF_SSL
|
||||
// if (getBindAdapter()->getEndpoint().isSSL())
|
||||
// {
|
||||
// //assert(_openssl->isHandshaked());
|
||||
//
|
||||
// int ret = _openssl->write(buff.c_str(), buff.length(), _sendBuffer);
|
||||
// if (ret != 0)
|
||||
// {
|
||||
// _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send direct error! " + TC_Common::tostr(ret));
|
||||
// return -1; // should not happen
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// else
|
||||
//#endif
|
||||
// {
|
||||
// _sendBuffer.addBuffer(buff);
|
||||
// }
|
||||
//
|
||||
// return sendBuffer();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send direct not support udp! ");
|
||||
// return -2;
|
||||
// }
|
||||
}
|
||||
|
||||
int TC_EpollServer::Connection::sendBufferDirect(const std::string& buff)
|
||||
{
|
||||
return sendBufferDirect(buff.data(), buff.length());
|
||||
}
|
||||
|
||||
int TC_EpollServer::Connection::sendBufferDirect(const shared_ptr<TC_NetWorkBuffer::Buffer>& buff)
|
||||
{
|
||||
_pBindAdapter->increaseSendBufferSize();
|
||||
|
||||
if(getBindAdapter()->getEndpoint().isTcp()) {
|
||||
|
||||
return _trans->sendRequest(buff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TC_EpollServer::Connection::checkFlow(TC_NetWorkBuffer& sendBuffer, size_t lastLeftBufferSize)
|
||||
{
|
||||
|
@ -1281,7 +1269,7 @@ TC_EpollServer::BindAdapter::BindAdapter(TC_EpollServer *epollServer)
|
|||
, _iQueueTimeout(DEFAULT_QUEUE_TIMEOUT)
|
||||
, _iHeaderLen(0)
|
||||
, _iHeartBeatTime(0)
|
||||
, _protocolName("taf")
|
||||
, _protocolName("tars")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1388,7 +1376,7 @@ const string &TC_EpollServer::BindAdapter::getProtocolName()
|
|||
|
||||
bool TC_EpollServer::BindAdapter::isTarsProtocol()
|
||||
{
|
||||
return (_protocolName == "taf");
|
||||
return (_protocolName == "tars" || _protocolName == "tars");
|
||||
}
|
||||
|
||||
bool TC_EpollServer::BindAdapter::isIpAllow(const string &ip) const
|
||||
|
|
|
@ -332,20 +332,23 @@ TC_NetWorkBuffer::PACKET_TYPE TC_GrpcServer::parseGrpc(TC_NetWorkBuffer&in, vect
|
|||
sessionPtr = session.get();
|
||||
}
|
||||
|
||||
if (sessionPtr->buffer().size() != 0) {
|
||||
vector<char> &buff = sessionPtr->buffer();
|
||||
|
||||
if (!buff.empty())
|
||||
{
|
||||
//直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
connection->sendBufferDirect(sessionPtr->buffer());
|
||||
sessionPtr->buffer().clear();
|
||||
connection->sendBufferDirect(buff.data(), buff.size());
|
||||
buff.clear();
|
||||
}
|
||||
|
||||
std::string inStr = in.getBuffersString();
|
||||
|
||||
auto ret = sessionPtr->parse(in, out);
|
||||
|
||||
if (sessionPtr->buffer().size() != 0) {
|
||||
if (!buff.empty()) {
|
||||
//直接发送裸得应答数据,业务层一般不直接使用,仅仅tcp支持
|
||||
connection->sendBufferDirect(sessionPtr->buffer());
|
||||
sessionPtr->buffer().clear();
|
||||
connection->sendBufferDirect(buff.data(), buff.size());
|
||||
buff.clear();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -13,7 +13,7 @@ void TC_HttpAsync::AsyncRequest::initialize(TC_Epoller *epoller, const TC_Endpoi
|
|||
{
|
||||
_callbackPtr = callbackPtr;
|
||||
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if(ep.isSSL())
|
||||
{
|
||||
_trans.reset(new TC_SSLTransceiver(epoller, ep));
|
||||
|
@ -47,7 +47,7 @@ shared_ptr<TC_ProxyInfo> TC_HttpAsync::AsyncRequest::onCreateCallback(TC_Transce
|
|||
|
||||
std::shared_ptr<TC_OpenSSL> TC_HttpAsync::AsyncRequest::onOpensslCallback(TC_Transceiver* trans)
|
||||
{
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if(trans->isSSL()) {
|
||||
if (!_pHttpAsync->getCtx()) {
|
||||
_ctx = TC_OpenSSL::newCtx("", "", "", false, "");
|
||||
|
|
|
@ -601,7 +601,7 @@ TC_Mysql::MysqlData TC_Mysql::queryRecord(const string& sSql)
|
|||
return data;
|
||||
}
|
||||
|
||||
size_t TC_Mysql::travelRecord(const string& sSql, const std::function<void(const map<string, string> &)> & pdatafunc)
|
||||
size_t TC_Mysql::travelRecord(const string& sSql, const std::function<void(const map<string, string> &)> & func)
|
||||
{
|
||||
size_t count = 0;
|
||||
/**
|
||||
|
@ -664,7 +664,7 @@ size_t TC_Mysql::travelRecord(const string& sSql, const std::function<void(const
|
|||
mpRow[vtFields[i]] = "";
|
||||
}
|
||||
}
|
||||
pdatafunc(mpRow);
|
||||
func(mpRow);
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,37 +272,40 @@ std::string TC_Port::exec(const char* cmd, std::string &err)
|
|||
return fileData;
|
||||
}
|
||||
|
||||
unordered_map<int, unordered_map<size_t, std::function<void()>>> TC_Port::_callbacks;
|
||||
std::mutex TC_Port::_mutex;
|
||||
std::atomic<size_t> TC_Port::_callbackId{0};
|
||||
shared_ptr<TC_Port::SigInfo> TC_Port::_sigInfo = std::make_shared<TC_Port::SigInfo>();
|
||||
|
||||
|
||||
size_t TC_Port::registerSig(int sig, std::function<void()> callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
std::lock_guard<std::mutex> lock(_sigInfo->_mutex);
|
||||
|
||||
auto it = _callbacks.find(sig);
|
||||
auto it = _sigInfo->_callbacks.find(sig);
|
||||
|
||||
if(it == _callbacks.end())
|
||||
if(it == _sigInfo->_callbacks.end())
|
||||
{
|
||||
//没有注册过, 才注册
|
||||
registerSig(sig);
|
||||
}
|
||||
|
||||
size_t id = ++_callbackId;
|
||||
size_t id = ++_sigInfo->_callbackId;
|
||||
|
||||
_callbacks[sig][id] = callback;
|
||||
_sigInfo->_callbacks[sig][id] = callback;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void TC_Port::unregisterSig(int sig, size_t id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto it = _callbacks.find(sig);
|
||||
|
||||
if(it != _callbacks.end())
|
||||
//注意_sigInfo是全局静态的, 有可能已经析构了, 需要特殊判断一下!
|
||||
if(_sigInfo && _sigInfo.use_count() > 0)
|
||||
{
|
||||
it->second.erase(id);
|
||||
std::lock_guard<std::mutex> lock(_sigInfo->_mutex);
|
||||
auto it = _sigInfo->_callbacks.find(sig);
|
||||
|
||||
if(it != _sigInfo->_callbacks.end())
|
||||
{
|
||||
it->second.erase(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,10 +366,10 @@ void TC_Port::sighandler( int sig_no )
|
|||
unordered_map<size_t, std::function<void()>> data;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
std::lock_guard<std::mutex> lock(_sigInfo->_mutex);
|
||||
|
||||
auto it = TC_Port::_callbacks.find(sig_no);
|
||||
if (it != TC_Port::_callbacks.end())
|
||||
auto it = TC_Port::_sigInfo->_callbacks.find(sig_no);
|
||||
if (it != TC_Port::_sigInfo->_callbacks.end())
|
||||
{
|
||||
data = it->second;
|
||||
}
|
||||
|
@ -393,10 +396,10 @@ BOOL WINAPI TC_Port::HandlerRoutine(DWORD dwCtrlType)
|
|||
unordered_map<size_t, std::function<void()>> data;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
std::lock_guard<std::mutex> lock(_sigInfo->_mutex);
|
||||
|
||||
auto it = TC_Port::_callbacks.find(dwCtrlType);
|
||||
if (it != TC_Port::_callbacks.end())
|
||||
auto it = _sigInfo->_callbacks.find(dwCtrlType);
|
||||
if (it != _sigInfo->_callbacks.end())
|
||||
{
|
||||
data = it->second;
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ void TC_Thread::coroutineEntry(TC_Thread *pThread, uint32_t iPoolSize, size_t iS
|
|||
});
|
||||
}
|
||||
|
||||
pThread->_scheduler->createCoroutine(std::bind(TC_Thread::threadEntry, pThread));
|
||||
pThread->_scheduler->go(std::bind(TC_Thread::threadEntry, pThread));
|
||||
|
||||
{
|
||||
TC_ThreadLock::Lock sync(pThread->_lock);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "util/tc_transceiver.h"
|
||||
#include "util/tc_logger.h"
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
#include "util/tc_openssl.h"
|
||||
#endif
|
||||
#include <sstream>
|
||||
|
@ -160,7 +160,7 @@ void TC_Transceiver::initializeServer(const onclose_callback &onclose,
|
|||
|
||||
_onOpensslCallback = onopenssl;
|
||||
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if (isSSL())
|
||||
{
|
||||
_openssl = _onOpensslCallback(this);
|
||||
|
@ -421,7 +421,7 @@ void TC_Transceiver::onConnect()
|
|||
|
||||
_epoller->erase(_connTimerId);
|
||||
_connTimerId = 0;
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if (isSSL())
|
||||
{
|
||||
_openssl = _onOpensslCallback(this);
|
||||
|
@ -468,7 +468,7 @@ void TC_Transceiver::doAuthReq()
|
|||
//如果是客户端, 则主动发起鉴权请求
|
||||
shared_ptr<TC_NetWorkBuffer::Buffer> buff = _onClientSendAuthCallback(this);
|
||||
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if(this->isSSL())
|
||||
{
|
||||
int ret = _openssl->write(buff->buffer(), (uint32_t) buff->length(), _sendBuffer);
|
||||
|
@ -569,7 +569,7 @@ void TC_Transceiver::tcpClose(bool deconstructor, CloseReason reason, const stri
|
|||
{
|
||||
if(_ep.isTcp() && isValid())
|
||||
{
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if (_openssl)
|
||||
{
|
||||
_openssl->release();
|
||||
|
@ -659,7 +659,7 @@ TC_Transceiver::ReturnStatus TC_Transceiver::sendRequest(const shared_ptr<TC_Net
|
|||
|
||||
if (_ep.isTcp() && _ep.getAuthType() == TC_Endpoint::AUTH_TYPELOCAL && _authState != eAuthSucc)
|
||||
{
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
if (isSSL() && !_openssl)
|
||||
{
|
||||
return eRetNotSend;
|
||||
|
@ -668,7 +668,7 @@ TC_Transceiver::ReturnStatus TC_Transceiver::sendRequest(const shared_ptr<TC_Net
|
|||
return eRetNotSend; // 需要鉴权但还没通过,不能发送非认证消息
|
||||
}
|
||||
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
// 握手数据已加密,直接发送,会话数据需加密
|
||||
if (isSSL())
|
||||
{
|
||||
|
@ -964,7 +964,7 @@ int TC_TCPTransceiver::recv(void* buf, uint32_t len, uint32_t flag)
|
|||
return iRet;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#if TAF_SSL
|
||||
#if TARS_SSL
|
||||
|
||||
TC_SSLTransceiver::TC_SSLTransceiver(TC_Epoller* epoller, const TC_Endpoint &ep)
|
||||
: TC_TCPTransceiver(epoller, ep)
|
||||
|
|
Loading…
Reference in New Issue