ruanshudong vor 2 Jahren
Ursprung
Commit
6b383550a5
87 geänderte Dateien mit 4788 neuen und 7389 gelöschten Zeilen
  1. 0 3
      .gitmodules
  2. 1 6
      CMakeLists.txt
  3. 14 12
      cmake/BuildTarsCpp.cmake
  4. 6 6
      cmake/Common.cmake
  5. 2 2
      examples/CoroutineDemo/testCoro/main.cpp
  6. 2 2
      examples/CoroutineDemo/testParallelCoro/main.cpp
  7. 6 2
      examples/CustomDemo/CustomClient/main.cpp
  8. 6 2
      examples/PushDemo/PushClient/TestRecvThread.cpp
  9. 1 1
      examples/UdpDemo/Client/main.cpp
  10. 82 59
      examples/UtilDemo/demo-server/demo_server.cpp
  11. 4 4
      servant/CMakeLists.txt
  12. 401 274
      servant/libservant/AdapterProxy.cpp
  13. 0 1
      servant/libservant/AdminServant.cpp
  14. 59 39
      servant/libservant/AppProtocol.cpp
  15. 193 191
      servant/libservant/Application.cpp
  16. 37 19
      servant/libservant/AsyncProcThread.cpp
  17. 117 136
      servant/libservant/AuthLogic.cpp
  18. 4 4
      servant/libservant/CMakeLists.txt
  19. 287 185
      servant/libservant/Communicator.cpp
  20. 405 334
      servant/libservant/CommunicatorEpoll.cpp
  21. 0 1026
      servant/libservant/CoroutineScheduler.cpp
  22. 48 10
      servant/libservant/Current.cpp
  23. 9 67
      servant/libservant/EndpointInfo.cpp
  24. 115 57
      servant/libservant/EndpointManager.cpp
  25. 5 3
      servant/libservant/Global.cpp
  26. 1 1
      servant/libservant/KeepAliveNodeF.cpp
  27. 0 87
      servant/libservant/NetworkUtil.cpp
  28. 74 91
      servant/libservant/ObjectProxy.cpp
  29. 0 75
      servant/libservant/ObjectProxyFactory.cpp
  30. 0 292
      servant/libservant/ProxyInfo.cpp
  31. 33 35
      servant/libservant/RemoteConfig.cpp
  32. 122 10
      servant/libservant/RemoteLogger.cpp
  33. 176 366
      servant/libservant/ServantHandle.cpp
  34. 405 250
      servant/libservant/ServantProxy.cpp
  35. 3 8
      servant/libservant/ServantProxyFactory.cpp
  36. 93 206
      servant/libservant/StatReport.cpp
  37. 0 900
      servant/libservant/Transceiver.cpp
  38. 15 15
      servant/makefile/makefile.tars
  39. 3 3
      servant/makefile/tars-tools.cmake
  40. 64 37
      servant/servant/AdapterProxy.h
  41. 25 17
      servant/servant/AppProtocol.h
  42. 64 48
      servant/servant/Application.h
  43. 3 16
      servant/servant/AuthLogic.h
  44. 4 4
      servant/servant/BaseNotify.h
  45. 176 55
      servant/servant/Communicator.h
  46. 226 91
      servant/servant/CommunicatorEpoll.h
  47. 3 3
      servant/servant/Cookie.h
  48. 0 704
      servant/servant/CoroutineScheduler.h
  49. 49 7
      servant/servant/Current.h
  50. 32 88
      servant/servant/EndpointInfo.h
  51. 27 7
      servant/servant/EndpointManager.h
  52. 38 58
      servant/servant/Global.h
  53. 88 103
      servant/servant/Message.h
  54. 0 38
      servant/servant/NetworkUtil.h
  55. 21 152
      servant/servant/ObjectProxy.h
  56. 0 190
      servant/servant/ProxyInfo.h
  57. 127 54
      servant/servant/RemoteLogger.h
  58. 0 1
      servant/servant/Servant.h
  59. 26 48
      servant/servant/ServantHandle.h
  60. 7 5
      servant/servant/ServantHelper.h
  61. 405 98
      servant/servant/ServantProxy.h
  62. 10 67
      servant/servant/StatReport.h
  63. 0 413
      servant/servant/Transceiver.h
  64. 536 137
      servant/tup/Tars.h
  65. 0 57
      servant/tup/tup.h
  66. 1 1
      tools/tars2android/main.cpp
  67. 2 2
      tools/tars2android/tars2android.h
  68. 3 3
      util/include/util/tc_coroutine.h
  69. 23 3
      util/include/util/tc_epoll_server.h
  70. 2 2
      util/include/util/tc_logger.h
  71. 3 3
      util/include/util/tc_mysql.h
  72. 1 1
      util/include/util/tc_network_buffer.h
  73. 1 1
      util/include/util/tc_openssl.h
  74. 13 9
      util/include/util/tc_port.h
  75. 1 1
      util/include/util/tc_proxy_info.h
  76. 1 1
      util/include/util/tc_thread.h
  77. 1 1
      util/include/util/tc_thread_cond.h
  78. 1 1
      util/include/util/tc_thread_mutex.h
  79. 4 1
      util/include/util/tc_uuid_generator.h
  80. 4 4
      util/src/tc_coroutine.cpp
  81. 23 35
      util/src/tc_epoll_server.cpp
  82. 9 6
      util/src/tc_grpc.cpp
  83. 2 2
      util/src/tc_http_async.cpp
  84. 2 2
      util/src/tc_mysql.cpp
  85. 22 19
      util/src/tc_port.cpp
  86. 1 1
      util/src/tc_thread.cpp
  87. 8 8
      util/src/tc_transceiver.cpp

+ 0 - 3
.gitmodules

@@ -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

+ 1 - 6
CMakeLists.txt

@@ -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()
 

+ 14 - 12
cmake/BuildTarsCpp.cmake

@@ -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}")

+ 6 - 6
cmake/Common.cmake

@@ -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}" )
 #-------------------------------------------------------------
 

+ 2 - 2
examples/CoroutineDemo/testCoro/main.cpp

@@ -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);

+ 2 - 2
examples/CoroutineDemo/testParallelCoro/main.cpp

@@ -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);

+ 6 - 2
examples/CustomDemo/CustomClient/main.cpp

@@ -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

+ 6 - 2
examples/PushDemo/PushClient/TestRecvThread.cpp

@@ -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);
 }
 

+ 1 - 1
examples/UdpDemo/Client/main.cpp

@@ -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");

+ 82 - 59
examples/UtilDemo/demo-server/demo_server.cpp

@@ -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);
-
-		//设置adapter名称, 唯一
-		lsPtr->setName("SocketAdapter");
-		//设置绑定端口
-		lsPtr->setEndpoint(str);
-		//设置最大连接数
-		lsPtr->setMaxConns(10240);
-		//设置启动线程数
-		lsPtr->setHandle<SocketHandle>(1);
-		//设置协议解析器
-		lsPtr->setProtocol(parseEcho);
-//		lsPtr->enableQueueMode();
+		TC_EpollServer::BindAdapterPtr adapter = this->createBindAdapter<SocketHandle>(str, str, 5);
+
+		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();
 
+		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("tcp -h 0.0.0.0 -p 8084 -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;
+}

+ 4 - 4
servant/CMakeLists.txt

@@ -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)

Datei-Diff unterdrückt, da er zu groß ist
+ 401 - 274
servant/libservant/AdapterProxy.cpp


+ 0 - 1
servant/libservant/AdminServant.cpp

@@ -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);
 }
 

+ 59 - 39
servant/libservant/AppProtocol.cpp

@@ -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;
-
-	buff.swap(os.getByteBuffer());
+	assert(os.getLength() >= 4);
 
-	assert(buff.size() >= 4);
+	iHeaderLen = htonl((int)(os.getLength()));
 
-	iHeaderLen = htonl((int)(buff.size()));
+	memcpy((void*)os.getBuffer(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
 
-	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);

+ 193 - 191
servant/libservant/Application.cpp

@@ -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,20 +179,36 @@ 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()
 {
     if (_epollServer && !_epollServer->isTerminate())
@@ -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);
+
+	    __out__.info() << os.str();
 
-        cout << "\n" << TC_Common::outfill("[initialize server] ", '.')  << " [Done]" << endl;
+	    __out__.info() << "\n" << TC_Common::outfill("[initialize server] ", '.')  << " [Done]" << endl;
 
-        cout << OUT_LINE_LONG << 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;
-
-        RemoteNotify::getInstance()->report("exit: " + string(ex.what()));
+	    __out__.error()  << "[main exception]:" << ex.what() << endl;
 
-	    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);
+
+	__out__.info() << os.str();
 
-    if (ServerConfig::NetThread < 1)
+	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);
     }

+ 37 - 19
servant/libservant/AsyncProcThread.cpp

@@ -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

+ 117 - 136
servant/libservant/AuthLogic.cpp

@@ -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

+ 4 - 4
servant/libservant/CMakeLists.txt

@@ -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)
 

+ 287 - 185
servant/libservant/Communicator.cpp

@@ -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 "";
 }
 
-#if TARS_SSL
-shared_ptr<TC_OpenSSL> Communicator::newClientSSL(const string &objName)
+
+shared_ptr<TC_OpenSSL> Communicator::newClientSSL(const string & objName)
 {
-    TC_LockT<TC_ThreadRecMutex> lock(*this);
+#if TARS_SSL
+	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);
-                }
-
-                _objCtx[auths[i]] = ctx;
-            }
+			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;
+			}
 #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);
     }
 
-    //异步队列数目上报
-    _reportAsyncQueue = getStatReport()->createPropertyReport(ClientConfig::ModuleName + ".asyncqueue", PropertyReport::avg());
+    {
+        std::unique_lock<std::mutex> lock(_mutex);
+        _cond.wait(lock, [&]{ return _communicatorEpollStartNum == clientThreadNum; });
+    }
 
+    //异步队列数目上报
+    _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;
 }
 
+vector<shared_ptr<CommunicatorEpoll>> Communicator::getAllCommunicatorEpoll()
+{
+	vector<shared_ptr<CommunicatorEpoll>> communicatorEpolls = _communicatorEpoll;
+
+	forEachSchedCommunicatorEpoll([&](const shared_ptr<CommunicatorEpoll> &c){
+		communicatorEpolls.push_back(c);
+	});
+
+	return communicatorEpolls;
+}
+
+void Communicator::forEachSchedCommunicatorEpoll(std::function<void(const shared_ptr<CommunicatorEpoll> &)> func)
+{
+	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 < _clientThreadNum; ++i)
+    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)
+int Communicator::reloadProperty(string & sResult)
 {
-    for (size_t i = 0; i < _clientThreadNum; ++i)
-    {
-        _communicatorEpoll[i]->getObjectProxyFactory()->loadObjectLocator();
-    }
+//    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)
+	    if(_statReport)
+		{
+			delete _statReport;
+			_statReport = NULL;
+		}
+        if(_servantProxyFactory)
         {
-            _statReport->getThreadControl().join();
-            delete _statReport;
-            _statReport = NULL;
+            delete _servantProxyFactory;
+            _servantProxyFactory = NULL; 
         }
 
-	    //delete网络线程
-        for (size_t i = 0; i < _clientThreadNum; ++i)
-        {
-        	if(_communicatorEpoll[i]) {
-		        delete _communicatorEpoll[i];
-		        _communicatorEpoll[i] = NULL;
-	        }
-        }
+		_communicatorEpoll.clear();
+		_schedCommunicatorEpoll.clear();
 
-        if (_servantProxyFactory)
-        {
-            delete _servantProxyFactory;
-            _servantProxyFactory = NULL;
-        }
     }
+
 }
 
-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;
 }

+ 405 - 334
servant/libservant/CommunicatorEpoll.cpp

@@ -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)
-{
-    _ep.create(1024);
+, _statQueue(MAX_STAT_QUEUE_SIZE)
 
-    _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)
-    {
-        if(_notify[i])
-        {
-            delete _notify[i];
-        }
-        _notify[i] = NULL;
-    }
-	
-    if(_objectProxyFactory)
-    {
-        delete _objectProxyFactory;
-        _objectProxyFactory = NULL;
-    }
+//     LOG_CONSOLE_DEBUG << endl;
 }
 
-void CommunicatorEpoll::terminate()
+void CommunicatorEpoll::handleServantThreadQuit(uint16_t iSeq)
 {
-    _terminate = true;
+	assert(_threadId == this_thread::get_id());
+
+	//在网络线程中处理的!
+    if(_notify[iSeq])
+	{
+        _notify[iSeq]->autoDestroy = true;
+
+        //通知网络线程, 网络线程好析构notify对象
+		notify(iSeq);
 
-	//通知epoll响应
-    _terminateFDInfo.notify.notify();
+        _notify[iSeq] = NULL;
+	}
 }
 
-void CommunicatorEpoll::notifyUpdateEndpoints(const ServantPrx &prx, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive)
+void CommunicatorEpoll::notifyServantThreadQuit(uint16_t iSeq)
 {
-	FDInfo *nfd = new FDInfo();
 
-	UpdateListInfo *p = new UpdateListInfo();
-	p->prx      = prx;
-	p->active   = active;
-	p->inactive = inactive;
-	nfd->p      = p;
+	if(_scheduler)
+	{
+		//CommunicatorEpoll还没有退出!
+		if (_threadId == this_thread::get_id())
+		{
+			//同一个线程里面结束, 直接释放相关资源即可
+			CommunicatorEpoll::handleServantThreadQuit(iSeq);
+		}
+		else
+		{
+            //等待数据都发送出去, 避免业务线程退出以后, 还有数据没有发送出去, 这里处理不够优雅!
+            {
+                std::lock_guard<std::mutex> lock(_mutex);
 
-	nfd->notify.init(&_ep);
-	nfd->iType = FDInfo::ET_C_UPDATE_LIST;
-	nfd->notify.add((uint64_t)nfd);
+                //再做一次判断
+                if (_scheduler)
+                {
+                    //通知网络线程去释放资源!
+                    _epoller->asyncCallback(std::bind(&CommunicatorEpoll::handleServantThreadQuit, this, iSeq));
+                }
+            }
+		}
+	}
 }
 
-ObjectProxy * CommunicatorEpoll::getObjectProxy(const string & sObjectProxyName,const string& setName)
+void CommunicatorEpoll::notifyTerminate()
 {
-    return _objectProxyFactory->getObjectProxy(sObjectProxyName,setName);
-}
+    if (_scheduler)
+    {
+        if(_threadId == this_thread::get_id())
+        {
+            //同一个线程里面结束, 直接释放相关资源即可
+            CommunicatorEpoll::handleTerminate();
+        }
+        else
+        {
+            std::lock_guard<std::mutex> lock(_mutex);
 
-int CommunicatorEpoll::addFd(int fd,FDInfo * info, uint32_t events)
-{
-    return _ep.add(fd, (uint64_t)info, events);
+            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;
+                // }
+            }
+        }
+    }
 }
 
-int CommunicatorEpoll::modFd(int fd,FDInfo * info, uint32_t events)
+void CommunicatorEpoll::handleTerminate()
 {
-    return _ep.mod(fd, (uint64_t)info, events);
+	assert(_threadId == this_thread::get_id());
+
+    if (_scheduler)
+    {
+        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;
+        }
+    }
 }
 
-int CommunicatorEpoll::delFd(int fd,FDInfo * info, uint32_t events)
+void CommunicatorEpoll::terminate()
 {
-    return _ep.del(fd, (uint64_t)info, events);
+    //通知网络线程退出, 不再执行任何操作
+	notifyTerminate();
 }
 
-//业务线程调用, 通知对应的网络线程醒过来
-//iSeq业务线程号
-void CommunicatorEpoll::notify(size_t iSeq, ReqInfoQueue * msgQueue)
+void CommunicatorEpoll::notifyUpdateEndpoints(ServantProxy *servantProxy, const set<EndpointInfo> & active,const set<EndpointInfo> & inactive)
 {
-    assert(iSeq < MAX_CLIENT_NOTIFYEVENT_NUM);
+    CommunicatorEpoll *ce = this;
 
-    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]);
-    }
-    else
-    {
-        _notify[iSeq]->notify.notify();
-    }
+    _epoller->asyncCallback([=]()
+                            { servantProxy->onNotifyEndpoints(ce, active, inactive); });
 }
 
-void CommunicatorEpoll::notifyDel(size_t iSeq)
+int CommunicatorEpoll::loadObjectLocator()
 {
-    assert(iSeq < MAX_CLIENT_NOTIFYEVENT_NUM);
-    if(_notify[iSeq] && NULL != _notify[iSeq]->p)
+	assert(_threadId == this_thread::get_id());
+
+    for (size_t i = 0; i < _objNum; i++)
     {
-        _notify[iSeq]->notify.notify();
+        _vObjectProxys[i]->loadLocator();
     }
+    return 0;
 }
 
-
-void CommunicatorEpoll::handleInputImp(Transceiver * pTransceiver)
+ObjectProxy* CommunicatorEpoll::servantToObjectProxy(ServantProxy *servantProxy)
 {
-    //检查连接是否有错误
-    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;
-        }
+	TC_ThreadRLock lock(_servantMutex);
 
-        pTransceiver->setConnected();
+	auto it = _servantObjectProxy.find(servantProxy);
+    if( it != _servantObjectProxy.end())
+    {
+        //当前线程(CommunicatorEpoll)还没有创建出对应的ObjectProxy
+        return it->second;
     }
 
-	pTransceiver->doResponse();
+//    assert(false);
+
+    return NULL;
 }
 
-void CommunicatorEpoll::handleOutputImp(Transceiver * pTransceiver)
+ObjectProxy * CommunicatorEpoll::hasObjectProxy(const string & sObjectProxyName,const string& setName)
 {
-    //检查连接是否有错误
-    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();
-    }
+	TC_LockT<TC_ThreadRecMutex> lock(_objectMutex);
 
-    pTransceiver->doRequest();
+	string tmpObjName = sObjectProxyName + "!" + setName;
+	auto it = _objectProxys.find(tmpObjName);
+	if(it != _objectProxys.end())
+	{
+		return it->second;
+	}
+
+	return NULL;
 }
 
-void CommunicatorEpoll::handle(FDInfo * pFDInfo, const epoll_event &ev)
+ObjectProxy * CommunicatorEpoll::createObjectProxy(ServantProxy *servantProxy, const string & sObjectProxyName, const string& setName)
 {
-	try
-    {
-        assert(pFDInfo != NULL);
+	ObjectProxy * pObjectProxy;
+	string tmpObjName = sObjectProxyName + "!" + setName;
+	{
+		TC_LockT<TC_ThreadRecMutex> lock(_objectMutex);
 
-        if(FDInfo::ET_C_TERMINATE == pFDInfo->iType)
-        {
-	        //结束通知过来
-            return;
-        }
-        else if(FDInfo::ET_C_UPDATE_LIST == pFDInfo->iType)
-        {
-	        UpdateListInfo *p = (UpdateListInfo*)pFDInfo->p;
+		auto it = _objectProxys.find(tmpObjName);
+		if (it != _objectProxys.end())
+		{
+			return it->second;
+		}
 
-	        assert(p && p->prx);
+	    pObjectProxy = new ObjectProxy(this, servantProxy, sObjectProxyName, setName);
 
-		    p->prx->onNotifyEndpoints(_netThreadSeq, p->active, p->inactive, false);
+		_objectProxys[tmpObjName] = pObjectProxy;
 
-	        pFDInfo->notify.release();
+	}
 
-	        delete p;
-	        delete pFDInfo;
+	{
+		TC_ThreadWLock lock(_vObjectMutex);
 
-	        return;
-        }
-        else if(FDInfo::ET_C_NOTIFY == pFDInfo->iType)
-        {
-            //队列有消息通知过来
-            ReqInfoQueue * pInfoQueue=(ReqInfoQueue*)pFDInfo->p;
-            ReqMessage * msg = NULL;
+		_vObjectProxys.push_back(pObjectProxy);
 
-	        size_t maxProcessCount = 0;
+		_objNum++;
+	}
 
-            try
-            {
-                while(pInfoQueue->pop_front(msg))
-                {
-                    //线程退出了
-                    if(ReqMessage::THREAD_EXIT == msg->eType)
-                    {
-                        assert(pInfoQueue->empty());
+	{
+		TC_ThreadWLock lock(_servantMutex);
 
-						size_t iSeq = pFDInfo->iSeq;
+		_servantObjectProxy[servantProxy] = pObjectProxy;
+	}
 
-						_notify[iSeq]->notify.release();
+	return pObjectProxy;
+}
 
-                        _notify[iSeq]->p = NULL;
+void CommunicatorEpoll::addFd(AdapterProxy* adapterProxy)
+{
+    shared_ptr<TC_Epoller::EpollInfo> epollInfo = adapterProxy->trans()->getEpollInfo();
 
-                        delete _notify[iSeq];
+    epollInfo->cookie(adapterProxy);
 
-                        _notify[iSeq] = NULL;
+	map<uint32_t, TC_Epoller::EpollInfo::EVENT_CALLBACK> callbacks;
 
-						//delete msg
-						delete msg;
+	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);
 
-						//delete queue
-						delete pInfoQueue;
+	epollInfo->registerCallback(callbacks, EPOLLIN|EPOLLOUT);
+}
 
-                        return;
-                    }
+void CommunicatorEpoll::notify(size_t iSeq)
+{
+	assert(_notify[iSeq] != NULL);
 
-                    try
-                    {
-	                    msg->pObjectProxy->invoke(msg);
-                    }
-                    catch(exception & e)
-                    {
-                        TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
-                    }
-                    catch(...)
-                    {
-                        TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
-                    }
+    // LOG_CONSOLE_DEBUG << "iSeq:" << iSeq << ", epollInfo:" << _notify[iSeq]->notify.getEpollInfo() << ", ce:" << this << 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);
-                }
-            }
+    _notify[iSeq]->notify.getEpollInfo()->mod(EPOLLOUT);
+}
 
-            //发包
-            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);
-                }
-            }
+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);
 
-        }
-    }
-    catch(exception & e)
+    if (_notify[iSeq] == NULL)
     {
-        TLOGERROR("CommunicatorEpoll::handle exp:"<<e.what()<<" ,line:"<<__LINE__<<endl);
+        _notify[iSeq] = new FDInfo();
+        _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);
     }
-    catch(...)
+    else
     {
-        TLOGERROR("CommunicatorEpoll::handle|"<<__LINE__<<endl);
+        _notify[iSeq]->msgQueue = msgQueue;
     }
 }
 
-void CommunicatorEpoll::doTimeout()
+bool CommunicatorEpoll::handleCloseImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
 {
-    int64_t iNow = TNOWMS;
-    if(_nextTime > iNow)
-    {
-        return;
-    }
+	assert(_threadId == this_thread::get_id());
 
-    //每_timeoutCheckInterval检查一次
-    _nextTime = iNow + _timeoutCheckInterval;
+	AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
 
-    for(size_t i = 0; i < _objectProxyFactory->getObjNum(); ++i)
-    {
-        _objectProxyFactory->getObjectProxy(i)->doTimeout();
-    }
+    adapterProxy->trans()->close();
+
+    return false;
 }
 
-void CommunicatorEpoll::doStat()
+bool CommunicatorEpoll::handleInputImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
 {
-    int64_t iNow = TNOW;
-    if(_nextStatTime > iNow)
-        return;
+	assert(_threadId == this_thread::get_id());
 
-    //10s上报一次
-    _nextStatTime = iNow + 10;
+	AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
 
-	if(isFirstNetThread()) {
-        _communicator->doStat();
+    try
+    {
+        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;
+}
 
-    StatReport::MapStatMicMsg mStatMicMsg;
+bool CommunicatorEpoll::handleOutputImp(const shared_ptr<TC_Epoller::EpollInfo> &data)
+{
+	assert(_threadId == this_thread::get_id());
 
-    for(size_t i = 0;i < _objectProxyFactory->getObjNum(); ++i)
+//	LOG_CONSOLE_DEBUG << endl;
+
+    AdapterProxy* adapterProxy = (AdapterProxy*)data->cookie();
+
+    try
+    {
+        adapterProxy->trans()->doRequest();
+    }
+    catch(const std::exception& e)
     {
-        _objectProxyFactory->getObjectProxy(i)->mergeStat(mStatMicMsg);
+//		LOG_CONSOLE_DEBUG << "[CommunicatorEpoll::handleOutputImp] error:" << e.what() << endl;
+
+		TLOGTARS("[CommunicatorEpoll::handleOutputImp] error:" << e.what() << endl);
+        adapterProxy->addConnExc(true);
+        return false;
     }
+    
+    return true;
+}
 
-    //有数据才上报
-    if(!mStatMicMsg.empty())
+void CommunicatorEpoll::report(StatReport::MapStatMicMsg *pmStatMicMsg)
+{
+    bool bFlag = _statQueue.push_back(pmStatMicMsg);
+    if(!bFlag)
     {
-        StatReport::MapStatMicMsg* pmStatMicMsg = new StatReport::MapStatMicMsg(mStatMicMsg);
-        _communicator->getStatReport()->report(_netThreadSeq,pmStatMicMsg);
+        delete pmStatMicMsg;
+        pmStatMicMsg = NULL;
+
+        TLOGERROR("[StatReport::report: queue full]" << endl);
     }
 }
 
-void CommunicatorEpoll::pushAsyncThreadQueue(ReqMessage * msg)
+bool CommunicatorEpoll::popStatMsg(StatReport::MapStatMicMsg* &mStatMsg)
+{
+    return _statQueue.pop_front(mStatMsg);
+}
+
+void CommunicatorEpoll::doTimeout()
 {
-    _communicator->pushAsyncThreadQueue(msg);
+	assert(_threadId == this_thread::get_id());
+
+	for(size_t i = 0; i < getObjNum(); ++i)
+    {
+        getObjectProxy(i)->doTimeout();
+    }
 }
 
-void CommunicatorEpoll::reConnect(int64_t ms, Transceiver*p)
+void CommunicatorEpoll::doStat()
 {
-    //如果节点已经存在,则不重复加入
-    for ( auto & item : _reconnect)
+	assert(_threadId == this_thread::get_id());
+
     {
-        if (item.second == p)
+        if(isFirstNetThread()) {
+            _communicator->doStat();
+        }
+
+        StatReport::MapStatMicMsg* pmStatMicMsg = new StatReport::MapStatMicMsg();//(mStatMicMsg);
+
+        for(size_t i = 0;i < getObjNum(); ++i)
+        {
+            getObjectProxy(i)->mergeStat(*pmStatMicMsg);
+        }
+
+        //有数据才上报
+        if(!pmStatMicMsg->empty())
+        {
+            report(pmStatMicMsg);
+        }
+        else
         {
-            return;
+            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)
-    {
-        try
-        {
-            //考虑到检测超时等的情况 这里就wait100ms吧
-            int num = _ep.wait(100);
+	// LOG_CONSOLE_DEBUG << endl;
 
-			if (_terminate) break;
+    //队列有消息通知过来
+    FDInfo *pFDInfo = (FDInfo*)data->cookie();
 
-	        //先处理epoll的网络事件
-            for (int i = 0; i < num; ++i)
-            {
-                const epoll_event& ev = _ep.get(i);
+    ReqMessage * msg = NULL;
 
-                uint64_t data = TC_Epoller::getU64(ev);
+    size_t maxProcessCount = 0;
 
-                if(data == 0) continue; //data非指针, 退出循环
+    try
+    {
+        while (pFDInfo->msgQueue->pop_front(msg))
+        {
+            msg->pObjectProxy->invoke(msg);
 
-//	            int64_t ms = TNOWMS;
+            if(++maxProcessCount > 1000)
+            {
+                //避免包太多的时候, 循环占用网路线程, 导致连接都建立不上, 一个包都无法发送出去
+				data->mod(EPOLLOUT);
 
-                handle((FDInfo*)data, ev);
+                TLOGTARS("[CommunicatorEpoll::handle max process count: " << maxProcessCount << ", fd:" << data->fd() << "]" << endl);
+                break;
             }
-
-            //处理超时请求
-            doTimeout();
-
-            //数据上报
-            doStat();
-	        reConnect();
-        }
-        catch (exception& e)
-        {
-            TLOGERROR("[CommunicatorEpoll:run exception:" << e.what() << "]" << endl);
         }
-        catch (...)
+
+        if (pFDInfo->msgQueue->empty() && pFDInfo->autoDestroy)
         {
-            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();
+
 }
 
 //////////////////////////////////////////////////////////////////////////////////

+ 0 - 1026
servant/libservant/CoroutineScheduler.cpp

@@ -1,1026 +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/CoroutineScheduler.h"
-
-#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-#include <algorithm>
-#include <cmath>
-#include <cstring>
-#include <stdexcept>
-#include <assert.h>
-#include "util/tc_timeprovider.h"
-
-#include "servant/RemoteLogger.h"
-#include "servant/ServantHandle.h"
-
-namespace tars 
-{
-
-#define MAX_WAIT_TIME_MS 1000
-#define MIN_WAIT_TIME_MS 1
-
-#if TARGET_PLATFORM_WINDOWS
-
-// x86_64
-// test x86_64 before i386 because icc might
-// define __i686__ for x86_64 too
-#if defined(__x86_64__) || defined(__x86_64) \
-    || defined(__amd64__) || defined(__amd64) \
-    || defined(_M_X64) || defined(_M_AMD64)
-
-// Windows seams not to provide a constant or function
-// telling the minimal stacksize
-# define MIN_STACKSIZE  8 * 1024
-#else
-# define MIN_STACKSIZE  4 * 1024
-#endif
-
-void system_info_( SYSTEM_INFO * si) {
-    ::GetSystemInfo( si);
-}
-
-SYSTEM_INFO system_info() {
-    static SYSTEM_INFO si;
-    static std::once_flag flag;
-    std::call_once( flag, static_cast< void(*)( SYSTEM_INFO *) >( system_info_), & si);
-    return si;
-}
-
-std::size_t pagesize() {
-    return static_cast< std::size_t >( system_info().dwPageSize);
-}
-
-// Windows seams not to provide a limit for the stacksize
-// libcoco uses 32k+4k bytes as minimum
-bool stack_traits::is_unbounded() {
-    return true;
-}
-
-std::size_t stack_traits::page_size() {
-    return pagesize();
-}
-
-std::size_t stack_traits::default_size() {
-    return 128 * 1024;
-}
-
-// because Windows seams not to provide a limit for minimum stacksize
-std::size_t stack_traits::minimum_size() {
-    return MIN_STACKSIZE;
-}
-
-// because Windows seams not to provide a limit for maximum stacksize
-// maximum_size() can never be called (pre-condition ! is_unbounded() )
-std::size_t stack_traits::maximum_size() {
-    assert( ! is_unbounded() );
-    return  1 * 1024 * 1024 * 1024; // 1GB
-}
-
-stack_context stack_traits::allocate(size_t size_) {
-	// calculate how many pages are required
-	const std::size_t pages(static_cast< std::size_t >( std::ceil( static_cast< float >( size_) / stack_traits::page_size() ) ) );
-	// add one page at bottom that will be used as guard-page
-	const std::size_t size__ = ( pages + 1) * stack_traits::page_size();
-
-	void * vp = ::VirtualAlloc( 0, size__, MEM_COMMIT, PAGE_READWRITE);
-	if ( ! vp) throw std::bad_alloc();
-
-	DWORD old_options;
-	const BOOL result = ::VirtualProtect(
-		vp, stack_traits::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
-	assert( FALSE != result);
-
-	stack_context sctx;
-	sctx.size = size__;
-	sctx.sp = static_cast< char * >( vp) + sctx.size;
-	return sctx;
-}
-
-void stack_traits::deallocate( stack_context & sctx)  {
-	assert( sctx.sp);
-
-	void * vp = static_cast< char * >( sctx.sp) - sctx.size;
-	::VirtualFree( vp, 0, MEM_RELEASE);
-}
-
-#else
-
-// 128kb recommended stack size
-// # define MINSIGSTKSZ (131072) 
-
-void pagesize_( std::size_t * size)  {
-    // conform to POSIX.1-2001
-    * size = ::sysconf( _SC_PAGESIZE);
-}
-
-void stacksize_limit_( rlimit * limit)  {
-    // conforming to POSIX.1-2001
-    ::getrlimit( RLIMIT_STACK, limit);
-}
-
-std::size_t pagesize()  {
-    static std::size_t size = 0;
-    static std::once_flag flag;
-    std::call_once( flag, pagesize_, & size);
-    return size;
-}
-
-rlimit stacksize_limit()  {
-    static rlimit limit;
-    static std::once_flag flag;
-    std::call_once( flag, stacksize_limit_, & limit);
-    return limit;
-}
-
-bool stack_traits::is_unbounded() {
-    return RLIM_INFINITY == stacksize_limit().rlim_max;
-}
-
-std::size_t stack_traits::page_size() {
-    return pagesize();
-}
-
-std::size_t stack_traits::default_size() {
-	return 128 * 1024;    
-}
-
-std::size_t stack_traits::minimum_size() {
-    return MINSIGSTKSZ;
-}
-
-std::size_t stack_traits::maximum_size() {
-    assert( ! is_unbounded() );
-    return static_cast< std::size_t >( stacksize_limit().rlim_max);
-}
-
-stack_context stack_traits::allocate(std::size_t size_) {
-	// calculate how many pages are required
-	const std::size_t pages(static_cast< std::size_t >( std::ceil( static_cast< float >( size_) / stack_traits::page_size() ) ) );
-	// add one page at bottom that will be used as guard-page
-	const std::size_t size__ = ( pages + 1) * stack_traits::page_size();
-
-	// conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
-#if defined(MAP_ANON)
-	void * vp = ::mmap( 0, size__, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-#else
-	void * vp = ::mmap( 0, size__, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#endif
-	if ( MAP_FAILED == vp) throw std::bad_alloc();
-
-	// conforming to POSIX.1-2001
-	const int result( ::mprotect( vp, stack_traits::page_size(), PROT_NONE) );
-	assert( 0 == result);
-
-	stack_context sctx;
-	sctx.size = size__;
-	sctx.sp = static_cast< char * >( vp) + sctx.size;
-
-	return sctx;
-}
-
-void stack_traits::deallocate(stack_context & sctx) {
-	assert( sctx.sp);
-
-	void * vp = static_cast< char * >( sctx.sp) - sctx.size;
-	// conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
-	::munmap( vp, sctx.size);
-}
-
-#endif
-
-////////////////////////////////////////////////////////
-CoroutineInfo::CoroutineInfo()
-: _prev(NULL)
-, _next(NULL)
-// , _main(true)
-, _scheduler(NULL)
-, _uid(0)
-, _eStatus(CORO_FREE)
-// , _ctx_to(NULL)
-{
-}
-
-CoroutineInfo::CoroutineInfo(CoroutineScheduler* scheduler)
-: _prev(NULL)
-, _next(NULL)
-// , _main(false)
-, _scheduler(scheduler)
-, _uid(0)
-, _eStatus(CORO_FREE)
-// , _ctx_to(NULL)
-{
-}
-
-CoroutineInfo::CoroutineInfo(CoroutineScheduler* scheduler, uint32_t iUid, stack_context stack_ctx)
-: _prev(NULL)
-, _next(NULL)
-// , _main(false)
-, _scheduler(scheduler)
-, _uid(iUid)
-, _eStatus(CORO_FREE)
-, _stack_ctx(stack_ctx)
-// , _ctx_to(NULL)
-{
-}
-
-CoroutineInfo::~CoroutineInfo()
-{
-}
-
-void CoroutineInfo::registerFunc(const std::function<void ()>& callback)
-{
-    _callback = callback;
-
-    _init_func.coroFunc = CoroutineInfo::corotineProc;
-
-    _init_func.args = this;
-
-    // _ctx_to = make_fcontext(_stack_ctx.sp, _stack_ctx.size, CoroutineInfo::corotineEntry);
-
-    // jump_fcontext(&_ctx_from, _ctx_to, (intptr_t)this, false);
-
-	fcontext_t ctx = make_fcontext(_stack_ctx.sp, _stack_ctx.size, CoroutineInfo::corotineEntry);
-
-	transfer_t tf = jump_fcontext(ctx, this);
-
-	//实际的ctx
-	this->setCtx(tf.fctx);
-}
-
-void CoroutineInfo::setStackContext(stack_context stack_ctx)
-{
-    _stack_ctx = stack_ctx;
-}
-
-void CoroutineInfo::corotineEntry(transfer_t tf)
-{
-    CoroutineInfo * coro = static_cast< CoroutineInfo * >(tf.data);
-
-    Func    func = coro->_init_func.coroFunc;
-    void*    args = coro->_init_func.args;
-
-    // jump_fcontext(coro->_ctx_to, &(coro->_ctx_from), 0, false);
-	transfer_t t = jump_fcontext(tf.fctx, NULL);
-
-	coro->_scheduler->setMainCtx(t.fctx);
-    try
-    {
-        func(args, t);
-    }
-    catch(std::exception &ex)
-    {
-        TLOGERROR("[CoroutineInfo::corotineEntry exception:" << ex.what() << endl);
-    }
-    catch(...)
-    {
-        TLOGERROR("[CoroutineInfo::corotineEntry unknown exception." << endl);
-    }
-}
-
-void CoroutineInfo::corotineProc(void * args, transfer_t t)
-{
-    CoroutineInfo *coro = (CoroutineInfo*)args;
-
-    try
-    {
-        std::function<void ()> cb = coro->_callback;
-
-        cb();
-    }
-    catch(std::exception &ex)
-    {
-        TLOGERROR("[CoroutineInfo::corotineProc exception:" << ex.what() << endl);
-    }
-    catch(...)
-    {
-        TLOGERROR("[CoroutineInfo::corotineProc unknown exception." << endl);
-    }
-
-    CoroutineScheduler* scheduler =  coro->getScheduler();
-    scheduler->decUsedSize();
-    scheduler->moveToFreeList(coro);
-
-	scheduler->switchCoro(&(scheduler->getMainCoroutine()));
-    // scheduler->switchCoro(coro, &(scheduler->getMainCoroutine()));
-    TLOGERROR("[CoroutineInfo::corotineProc no come." << endl);
-}
-
-//////////////////////////////////////////////////////////////
-CoroutineScheduler::CoroutineScheduler()
-: _terminal(false)
-, _poolSize(1000)
-, _stackSize(128*1024)
-, _currentSize(0)
-, _usedSize(0)
-, _uniqId(0)
-, _handle(NULL)
-, _currentCoro(NULL)
-, _all_coro(NULL)
-{
-    _all_coro = new CoroutineInfo*[_poolSize+1];
-    for(size_t i = 0; i <= _poolSize; ++i)
-    {
-        _all_coro[i] = NULL;
-    }
-
-    CoroutineInfo::CoroutineHeadInit(&_active);
-    CoroutineInfo::CoroutineHeadInit(&_avail);
-    CoroutineInfo::CoroutineHeadInit(&_inactive);
-    CoroutineInfo::CoroutineHeadInit(&_timeout);
-    CoroutineInfo::CoroutineHeadInit(&_free);
-}
-
-CoroutineScheduler::~CoroutineScheduler()
-{}
-
-void CoroutineScheduler::init(uint32_t iPoolSize, size_t iStackSize)
-{
-    if(iPoolSize <= 0)
-    {
-        TLOGERROR("[CoroutineScheduler::init iPoolSize <= 0." << endl);
-        return ;
-    }
-
-    _terminal = false;
-    _poolSize = iPoolSize;
-    _stackSize = iStackSize;
-
-    if(_poolSize <= 100)
-    {
-        _currentSize = _poolSize;
-    }
-    else
-    {
-        _currentSize = 100;
-    }
-
-    if(_all_coro != NULL)
-    {
-        delete [] _all_coro;
-        _all_coro = new CoroutineInfo*[_poolSize+1];
-        for(size_t i = 0; i <= _poolSize; ++i)
-        {
-            _all_coro[i] = NULL;
-        }
-    }
-
-    _usedSize = 0;
-    _uniqId = 0;
-
-    int iSucc = 0;
-    for(size_t i = 0; i < _currentSize; ++i)
-    {
-        CoroutineInfo *coro = new CoroutineInfo(this);
-
-        // stack_context s_ctx;
-        // int ret = _alloc.allocate(s_ctx, iStackSize);
-        // if(ret != 0)
-        // {
-        //     TLOGERROR("[CoroutineScheduler::init iPoolSize:" << iPoolSize << "|iStackSize:" << iStackSize << "|i:" << i << endl);
-
-        //     delete coro;
-        //     coro = NULL;
-        //     break;
-        // }
-
-		stack_context s_ctx = stack_traits::allocate(iStackSize);
-
-        coro->setStackContext(s_ctx);
-
-        uint32_t iId = generateId();
-        coro->setUid(iId);
-        coro->setStatus(CORO_FREE);
-
-        //_free.push_front(coro);
-
-        //_all.insert(make_pair(coro->getUid(), coro));
-
-        _all_coro[iId] = coro;
-
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-
-        ++iSucc;
-    }
-
-    _currentSize = iSucc;
-
-    _mainCoro.setUid(0);
-    _mainCoro.setStatus(CORO_FREE);
-
-    _currentCoro = &_mainCoro;
-
-    TLOGDEBUG("[CoroutineScheduler::init iPoolSize:" << _poolSize << "|iCurrentSize:" << _currentSize << "|iStackSize:" << _stackSize << endl);
-}
-
-int    CoroutineScheduler::increaseCoroPoolSize()
-{
-    int iInc = ((_poolSize - _currentSize) > 100) ? 100 : (_poolSize - _currentSize);
-    if(iInc <= 0)
-    {
-        TLOGERROR("[CoroutineScheduler::increaseCoroPoolSize full iPoolSize:" << _poolSize << "|iCurrentSize:" << _currentSize << endl);
-        return -1;
-    }
-
-    int iSucc = 0;
-    for(int i = 0; i < iInc; ++i)
-    {
-        CoroutineInfo *coro = new CoroutineInfo(this);
-        uint32_t iId = generateId();
-        coro->setUid(iId);
-        coro->setStatus(CORO_FREE);
-
-        // stack_context s_ctx;
-        // int ret = _alloc.allocate(s_ctx, _stackSize);
-        // if(ret != 0)
-        // {
-        //     TLOGERROR("[CoroutineScheduler::increaseCoroPoolSize iPoolSize:" << _poolSize << "|iStackSize:" << _stackSize << "|i:" << i << endl);
-
-        //     delete coro;
-        //     coro = NULL;
-        //     break;
-        // }
-
-		stack_context s_ctx = stack_traits::allocate(_stackSize);
-
-        coro->setStackContext(s_ctx);
-
-        _all_coro[iId] = coro;
-
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-
-        ++iSucc;
-    }
-
-    if(iSucc == 0)
-    {
-        TLOGERROR("[CoroutineScheduler::increaseCoroPoolSize cannot create iInc:" << iInc << "|iPoolSize:" << _poolSize << endl);
-        return -1;
-    }
-
-    _currentSize += iSucc;
-
-    return 0;
-}
-
-uint32_t CoroutineScheduler::createCoroutine(const std::function<void ()> &callback)
-{
-    if(_usedSize >= _currentSize || CoroutineInfo::CoroutineHeadEmpty(&_free))
-    {
-        int iRet = increaseCoroPoolSize();
-
-        if(iRet != 0)
-            return 0;
-    }
-
-    CoroutineInfo *coro = _free._next;
-    assert(coro != NULL);
-
-    CoroutineInfo::CoroutineDel(coro);
-
-    _usedSize++;
-
-    coro->setStatus(CORO_AVAIL);
-
-    CoroutineInfo::CoroutineAddTail(coro, &_avail);
-
-    coro->registerFunc(callback);
-
-    return coro->getUid();
-}
-
-void CoroutineScheduler::run()
-{
-    while(!_terminal)
-    {
-        wakeupbyself();
-
-        if(!CoroutineInfo::CoroutineHeadEmpty(&_avail))
-        {
-            CoroutineInfo *coro = _avail._next;
-
-            assert(coro != NULL);
-
-            // switchCoro(&_mainCoro, coro);
-            switchCoro(coro);
-
-        }
-
-        //获取第一个即将timeout的剩余时长
-        int waitTime = wakeupbytimeout();
-
-        if(CoroutineInfo::CoroutineHeadEmpty(&_active) && (_activeCoroQueue.size() <= 0))
-        {
-            waitTime = min(max(waitTime, MIN_WAIT_TIME_MS), MAX_WAIT_TIME_MS);
-            TC_ThreadLock::Lock lock(_monitor);
-            //限定最多等待时长为waitTime,尽量保证sleep的协程及时被唤醒
-            _monitor.timedWait(waitTime);
-        }
-
-        wakeup();
-
-        if(!CoroutineInfo::CoroutineHeadEmpty(&_active))
-        {
-            int iLoop = 100;
-            while(iLoop > 0 && !CoroutineInfo::CoroutineHeadEmpty(&_active))
-            {
-                CoroutineInfo *coro = _active._next;
-
-                assert(coro != NULL);
-
-                // switchCoro(&_mainCoro, coro);
-                switchCoro(coro);
-
-                --iLoop;
-            }
-
-        }
-
-        if(_usedSize == 0)
-            break;
-    }
-
-    destroy();
-}
-
-void CoroutineScheduler::tars_run()
-{
-    if(!_terminal)
-    {
-        wakeupbytimeout();
-
-        wakeupbyself();
-
-        wakeup();
-
-        if(!CoroutineInfo::CoroutineHeadEmpty(&_active))
-        {
-            int iLoop = 100;
-            while(iLoop > 0 && !CoroutineInfo::CoroutineHeadEmpty(&_active))
-            {
-                CoroutineInfo *coro = _active._next;
-
-                assert(coro != NULL);
-
-                // switchCoro(&_mainCoro, coro);
-                switchCoro(coro);
-
-                --iLoop;
-            }
-
-        }
-
-        if(!CoroutineInfo::CoroutineHeadEmpty(&_avail))
-        {
-            int iLoop = 100;
-            while(iLoop > 0 && !CoroutineInfo::CoroutineHeadEmpty(&_avail))
-            {
-                CoroutineInfo *coro = _avail._next;
-
-                assert(coro != NULL);
-
-                // switchCoro(&_mainCoro, coro);
-                switchCoro(coro);
-
-                --iLoop;
-            }
-
-        }
-    }
-}
-
-void CoroutineScheduler::yield(bool bFlag)
-{
-    if(bFlag)
-    {
-        putbyself(_currentCoro->getUid());
-    }
-
-    moveToInactive(_currentCoro);
-    // switchCoro(_currentCoro, &_mainCoro);
-    switchCoro(&_mainCoro);
-}
-
-void CoroutineScheduler::sleep(int iSleepTime)
-{
-    int64_t iNow = TNOWMS;
-    int64_t iTimeout = iNow + (iSleepTime >= 0 ? iSleepTime : -iSleepTime);
-
-    _timeoutCoroId.insert(make_pair(iTimeout, _currentCoro->getUid()));
-
-    moveToTimeout(_currentCoro);
-    // switchCoro(_currentCoro, &_mainCoro);
-    switchCoro(&_mainCoro);
-}
-
-void CoroutineScheduler::putbyself(uint32_t iCoroId)
-{
-    if(!_terminal)
-    {
-        _needActiveCoroId.push_back(iCoroId);
-    }
-}
-
-void CoroutineScheduler::wakeupbyself()
-{
-    if(!_terminal)
-    {
-        if(_needActiveCoroId.size() > 0)
-        {
-            list<uint32_t>::iterator it = _needActiveCoroId.begin();
-            while(it != _needActiveCoroId.end())
-            {
-                CoroutineInfo *coro = _all_coro[*it];
-
-                assert(coro != NULL);
-
-                moveToAvail(coro);
-
-                ++it;
-            }
-            _needActiveCoroId.clear();
-        }
-    }
-}
-
-void CoroutineScheduler::put(uint32_t iCoroId)
-{
-    if(!_terminal)
-    {
-        _activeCoroQueue.push_back(iCoroId);
-
-        if(_handle)
-        {
-            _handle->notifyFilter();
-        }
-        else
-        {
-            TC_ThreadLock::Lock lock(_monitor);
-
-            _monitor.notifyAll();
-        }
-    }
-}
-
-void CoroutineScheduler::wakeup()
-{
-    if(!_terminal)
-    {
-        if(_activeCoroQueue.size() > 0)
-        {
-
-            TC_ThreadQueue<uint32_t, deque<uint32_t> >::queue_type coroIds;
-            _activeCoroQueue.swap(coroIds);
-
-            TC_ThreadQueue<uint32_t, deque<uint32_t> >::queue_type::iterator it = coroIds.begin();
-
-            TC_ThreadQueue<uint32_t, deque<uint32_t> >::queue_type::iterator itEnd = coroIds.end();
-
-            while(it != itEnd)
-            {
-                CoroutineInfo *coro = _all_coro[*it];
-
-                assert(coro != NULL);
-
-                moveToActive(coro);
-
-                ++it;
-            }
-
-        }
-    }
-}
-
-int CoroutineScheduler::wakeupbytimeout()
-{
-    int leftTime = MAX_WAIT_TIME_MS;
-    if(!_terminal)
-    {
-        if(_timeoutCoroId.size() > 0)
-        {
-            int64_t iNow = TNOWMS;
-            while(true)
-            {
-                multimap<int64_t, uint32_t>::iterator it = _timeoutCoroId.begin();
-
-                if(it == _timeoutCoroId.end())
-                    break;
-
-                leftTime = it->first - iNow;
-                if(leftTime > 0)
-                    break;
-
-                CoroutineInfo *coro = _all_coro[it->second];
-
-                assert(coro != NULL);
-
-                moveToActive(coro);
-
-                _timeoutCoroId.erase(it);
-            }
-
-        }
-    }
-    return leftTime;
-}
-
-void CoroutineScheduler::terminate()
-{
-    _terminal = true;
-
-    if(_handle)
-    {
-        _handle->notifyFilter();
-    }
-    else
-    {
-        TC_ThreadLock::Lock lock(_monitor);
-
-        _monitor.notifyAll();
-    }
-}
-
-uint32_t CoroutineScheduler::generateId()
-{
-    uint32_t i = ++_uniqId;
-    if(i == 0) {
-        i = ++_uniqId;
-    }
-
-    assert(i <= _poolSize);
-
-    return i;
-}
-
-// void CoroutineScheduler::switchCoro(CoroutineInfo *from, CoroutineInfo *to)
-void CoroutineScheduler::switchCoro(CoroutineInfo *to)
-{
-    _currentCoro = to;
-
-    // jump_fcontext(from->getCtx(), to->getCtx(), 0, false);
-	transfer_t t = jump_fcontext(to->getCtx(), NULL);
-	to->setCtx(t.fctx);
-}
-
-void CoroutineScheduler::moveToActive(CoroutineInfo *coro, bool bFlag)
-{
-    if(coro->getStatus() == CORO_INACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_ACTIVE);
-        CoroutineInfo::CoroutineAddTail(coro, &_active);
-    }
-    else if(coro->getStatus() == CORO_TIMEOUT)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_ACTIVE);
-        CoroutineInfo::CoroutineAddTail(coro, &_active);
-    }
-    else
-    {
-        TLOGERROR("[CoroutineScheduler::moveToActive ERROR|iCoroId:" << coro->getUid() << "|tyep:" << coro->getStatus() << endl);
-    }
-}
-
-void CoroutineScheduler::moveToAvail(CoroutineInfo *coro)
-{
-    if(coro->getStatus() == CORO_INACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_AVAIL);
-        CoroutineInfo::CoroutineAddTail(coro, &_avail);
-    }
-    else
-    {
-        TLOGERROR("[CoroutineScheduler::moveToAvail ERROR:|iCoroId:" << coro->getUid() << "|tyep:" << coro->getStatus() << endl);
-    }
-}
-
-void CoroutineScheduler::moveToInactive(CoroutineInfo *coro)
-{
-    if(coro->getStatus() == CORO_ACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_INACTIVE);
-        CoroutineInfo::CoroutineAddTail(coro, &_inactive);
-    }
-    else if(coro->getStatus() == CORO_AVAIL)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_INACTIVE);
-        CoroutineInfo::CoroutineAddTail(coro, &_inactive);
-    }
-    else
-    {
-        TLOGERROR("[CoroutineScheduler::moveToInactive ERROR|iCoroId:" << coro->getUid() << "|tyep:" << coro->getStatus() << endl);
-    }
-}
-
-void CoroutineScheduler::moveToTimeout(CoroutineInfo *coro)
-{
-    if(coro->getStatus() == CORO_ACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_TIMEOUT);
-        CoroutineInfo::CoroutineAddTail(coro, &_timeout);
-    }
-    else if(coro->getStatus() == CORO_AVAIL)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_TIMEOUT);
-        CoroutineInfo::CoroutineAddTail(coro, &_timeout);
-    }
-    else
-    {
-        TLOGERROR("[CoroutineScheduler::moveToTimeout ERROR|iCoroId:" << coro->getUid() << "|tyep:" << coro->getStatus() << endl);
-    }
-}
-
-void CoroutineScheduler::moveToFreeList(CoroutineInfo *coro)
-{
-    if(coro->getStatus() == CORO_ACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_FREE);
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-    }
-    else if(coro->getStatus() == CORO_AVAIL)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_FREE);
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-    }
-    else if(coro->getStatus() == CORO_INACTIVE)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_FREE);
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-    }
-    else if(coro->getStatus() == CORO_TIMEOUT)
-    {
-        CoroutineInfo::CoroutineDel(coro);
-        coro->setStatus(CORO_FREE);
-        CoroutineInfo::CoroutineAddTail(coro, &_free);
-    }
-    else
-    {
-        TLOGERROR("[CoroutineScheduler::moveToFreeList ERROR: already free|iCoroId:" << coro->getUid() << "|tyep:" << coro->getStatus() << endl);
-    }
-}
-
-void CoroutineScheduler::destroy()
-{
-    if(_all_coro)
-    {
-        for(size_t i = 1; i <= _poolSize; i++)
-        {
-            if(_all_coro[i])
-            {
-                stack_traits::deallocate(_all_coro[i]->getStackContext());
-            }
-        }
-        delete [] _all_coro;
-    }
-}
-/////////////////////////////////////////////////////////
-Coroutine::Coroutine()
-: _coroSched(NULL)
-, _num(1)
-, _maxNum(128)
-, _stackSize(128*1024)
-{
-}
-
-Coroutine::~Coroutine()
-{
-    if(isAlive())
-    {
-        terminate();
-
-        getThreadControl().join();
-    }
-}
-
-void Coroutine::setCoroInfo(uint32_t iNum, uint32_t iMaxNum, size_t iStackSize)
-{
-    _maxNum = (iMaxNum > 0 ? iMaxNum : 1);
-    _num = (iNum > 0 ? (iNum <= _maxNum ? iNum : _maxNum) : 1);
-    _stackSize = (iStackSize >= pagesize() ? iStackSize : pagesize());
-}
-
-void Coroutine::run()
-{
-    initialize();
-
-    handleCoro();
-
-    destroy();
-}
-
-void Coroutine::terminate()
-{
-    if(_coroSched)
-    {
-        _coroSched->terminate();
-    }
-}
-
-void Coroutine::handleCoro()
-{
-    _coroSched = new CoroutineScheduler();
-
-    _coroSched->init(_maxNum, _stackSize);
-
-    ServantProxyThreadData * pSptd = ServantProxyThreadData::getData();
-
-    assert(pSptd != NULL);
-
-    pSptd->_sched = _coroSched;
-
-    for(uint32_t i = 0; i < _num; ++i)
-    {
-        _coroSched->createCoroutine(std::bind(&Coroutine::coroEntry, this));
-    }
-
-    _coroSched->run();
-
-    delete _coroSched;
-    _coroSched = NULL;
-}
-
-void Coroutine::coroEntry(Coroutine *pCoro)
-{
-    try
-    {
-        pCoro->handle();
-    }
-    catch(exception &ex)
-    {
-        TLOGERROR("[Coroutine::coroEntry exception:" << ex.what() << "]" << endl);
-    }
-    catch(...)
-    {
-        TLOGERROR("[Coroutine::coroEntry unknown exception]" << endl);
-    }
-}
-
-uint32_t Coroutine::createCoroutine(const std::function<void ()> &coroFunc)
-{
-    if(_coroSched)
-    {
-        return _coroSched->createCoroutine(coroFunc);
-    }
-    else
-    {
-        TLOGERROR("[Coroutine::createCoroutine coro sched no init]" << endl);
-    }
-    return -1;
-}
-
-void Coroutine::yield()
-{
-    if(_coroSched)
-    {
-        _coroSched->yield();
-    }
-    else
-    {
-        throw CoroutineException("[Coroutine::yield coro sched no init]");
-    }
-}
-
-void Coroutine::Sleep(int iSleepTime)
-{
-    if(_coroSched)
-    {
-        _coroSched->sleep(iSleepTime);
-    }
-    else
-    {
-        throw CoroutineException("[Coroutine::yield coro sched no init]");
-    }
-}
-
-}

+ 48 - 10
servant/libservant/Current.cpp

@@ -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();
+}
+
+
 ////////////////////////////////////////////////////////////////////////////
 }

+ 9 - 67
servant/libservant/EndpointInfo.cpp

@@ -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,23 +48,15 @@ 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()
 {
 	stringstream ss;
@@ -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;
-}
 ///////////////////////////////////////////////////////////
 }

+ 115 - 57
servant/libservant/EndpointManager.cpp

@@ -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)
 {
-    setNoDelete(true);
-
-    _refreshInterval = TC_Common::strto<int>(_communicator->getProperty("refresh-endpoint-interval", "60000"));
+    _refreshInterval = TC_Common::strto<int>(_communicator->getProperty("refresh-endpoint-interval", "60*1000"));
 
-    TLOGTARS("[QueryEpBase _refreshInterval:" << _refreshInterval << "]" << endl);
+    if(_refreshInterval < 5*1000)
+    {
+        _refreshInterval = 5 * 1000;
+    }
+    setNoDelete(true);
 }
 
 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);

+ 5 - 3
servant/libservant/Global.cpp

@@ -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);
     }
 }
 ////////////////////////////////////////////////////////////////////////////

+ 1 - 1
servant/libservant/KeepAliveNodeF.cpp

@@ -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"

+ 0 - 87
servant/libservant/NetworkUtil.cpp

@@ -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);
-// }
-
-
-

+ 74 - 91
servant/libservant/ObjectProxy.cpp

@@ -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()
+{
 
 }
 
-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();
+            }
+        }
 	}
 }
 

+ 0 - 75
servant/libservant/ObjectProxyFactory.cpp

@@ -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;
-}
-///////////////////////////////////////////////////////////////////
-}

+ 0 - 292
servant/libservant/ProxyInfo.cpp

@@ -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;
-}
-
-}

+ 33 - 35
servant/libservant/RemoteConfig.cpp

@@ -101,42 +101,40 @@ string RemoteConfig::getRemoteFile(const string &sFileName, bool bAppConfigOnly)
 {
     if (_configPrx)
     {
-       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);
-                }
-                
-                break;
-           }catch(std::exception& e){
-            //
-           }catch (...){
-            //
-           }
-       }
+       	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);
+       			}
+
+       			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));
 

+ 122 - 10
servant/libservant/RemoteLogger.cpp

@@ -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;
+}
+
 }

+ 176 - 366
servant/libservant/ServantHandle.cpp

@@ -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 &current)
-{
-    if(!(Application::getCommunicator()->_traceManager))
-    {
-        return;
-    }
-    ServantProxyThreadData * sptd = ServantProxyThreadData::getData();
-    assert(sptd);
+// #ifdef TARS_OPENTRACKING
+// void ServantHandle::processTracking(const TarsCurrentPtr &current)
+// {
+//     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);
-
-            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())});
+//             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 ;
+//             }
+
+//             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 &current)
-{
-    int requestId = current->getRequestId();
+// void ServantHandle::finishTracking(int ret, const TarsCurrentPtr &current)
+// {
+//     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 &current, 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 &current, string& dyeingKey)
 		}
 	}
 
-    return false;
+	return false;
 }
 
 
@@ -718,12 +531,12 @@ bool ServantHandle::processCookie(const CurrentPtr &current, map<string, string>
 
 bool ServantHandle::checkValidSetInvoke(const CurrentPtr &current)
 {
-    /*是否允许检查合法性*/
-    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 &current)
         {
             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 &current)
         }
     }
 
-    //没有按set规则调用
-    return true;
+	//没有按set规则调用
+	return true;
 }
 
 void ServantHandle::handleTarsProtocol(const CurrentPtr &current)
@@ -807,11 +620,11 @@ void ServantHandle::handleTarsProtocol(const CurrentPtr &current)
                 << 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 &current)
         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
     {
         //业务逻辑处理

Datei-Diff unterdrückt, da er zu groß ist
+ 405 - 250
servant/libservant/ServantProxy.cpp


+ 3 - 8
servant/libservant/ServantProxyFactory.cpp

@@ -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"));

+ 93 - 206
servant/libservant/StatReport.cpp

@@ -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;
-                   }
-
-                   if(bFlag)
+                //    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)
                    {
                         StatPropInfo sp;
                         sp.policy = v[i].first;
@@ -622,115 +566,60 @@ 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;
-    }
-    catch ( exception& e )
-    {
-        TLOGERROR("StatReport::reportPropMsg catch exception:" << e.what() << endl);
-    }
-    catch ( ... )
-    {
-        TLOGERROR("StatReport::reportPropMsg catch unkown exception" << endl);
-    }
-    return -1;
-}
-
-int StatReport::reportSampleMsg()
-{
-    try
-    {
-        MMapStatSampleMsg mmStatSampleMsg;
-        {
-            Lock lock(*this);
-            _statSampleMsg.swap(mmStatSampleMsg);
-        }
-
-        TLOGTARS("[StatReport::reportSampleMsg get size:" << mmStatSampleMsg.size()<<"]"<< endl);
-
+        TLOGTARS("[StatReport::reportPropMsg get size:" << mStatMsg.size() << "]" << endl);
         int iLen = 0;
-        vector<StatSampleMsg> vTemp;
-        for(MMapStatSampleMsg::const_iterator it = mmStatSampleMsg.begin() ;it != mmStatSampleMsg.end();++it)
+        MapStatPropMsg mTemp;
+        for (MapStatPropMsg::iterator it = mStatMsg.begin(); it != mStatMsg.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);
+            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)vTemp.size())
+        if (0 != (int)mTemp.size())
         {
-           if(_statPrx)
-           {
-               TLOGTARS("[StatReport::reportSampleMsg send size:" << vTemp.size()<< "]"<< endl);
-               _statPrx->tars_set_timeout(_reportTimeout)->async_reportSampleMsg(NULL,vTemp, ServerConfig::Context);
-           }
+            if (_propertyPrx)
+            {
+                TLOGTARS("[StatReport::reportPropMsg send size:" << mTemp.size() << "]" << endl);
+                _propertyPrx->tars_set_timeout(_reportTimeout)->async_reportPropMsg(NULL, mTemp);
+            }
         }
-
         return 0;
     }
     catch ( exception& e )
     {
-        TLOGERROR("[StatReport::reportSampleMsg catch exception:" << e.what() << "]" << endl);
+        TLOGERROR("StatReport::reportPropMsg catch exception:" << e.what() << endl);
     }
     catch ( ... )
     {
-        TLOGERROR("[StatReport::reportSampleMsg catch unkown exception]" << endl);
+        TLOGERROR("StatReport::reportPropMsg 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();
 }
 
 ////////////////////////////////////////////////////////////////

+ 0 - 900
servant/libservant/Transceiver.cpp

@@ -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;
-}
-
-/////////////////////////////////////////////////////////////////
-}

+ 15 - 15
servant/makefile/makefile.tars

@@ -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
 
 #-----------------------------------------------------------------------------
 

+ 3 - 3
servant/makefile/tars-tools.cmake

@@ -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")

+ 64 - 37
servant/servant/AdapterProxy.h

@@ -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;
 };

+ 25 - 17
servant/servant/AppProtocol.h

@@ -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

+ 64 - 48
servant/servant/Application.h

@@ -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 - 16
servant/servant/AuthLogic.h

@@ -3,28 +3,15 @@
 
 namespace tars
 {
-
-/**
- * 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 :默认鉴权方法
+ * 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
 

+ 4 - 4
servant/servant/BaseNotify.h

@@ -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;
 
 };

+ 176 - 55
servant/servant/Communicator.h

@@ -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];
 
-    /*
-     * 网络线程数目
+    /**
+     * 私有网络线程, 会动态变化
+     */
+    unordered_map<size_t, shared_ptr<CommunicatorEpoll>>	_schedCommunicatorEpoll;
+
+    /**
+     * 操作通信器的锁
      */
-    size_t                 _clientThreadNum;
-  
+    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;
-
-#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
+	
+    /**
+     * 注册事件
+     */
+    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();}}
+//     };
+
+//     TC_AutoPtr<TraceManager> _traceManager;
+// #endif
 
 };
 ////////////////////////////////////////////////////////////////////////

+ 226 - 91
servant/servant/CommunicatorEpoll.h

@@ -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
-     */
-    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
+     * @param adapterProxy
      */
-    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
+     */
+    bool handleCloseImp(const shared_ptr<TC_Epoller::EpollInfo> &data);
 
     /**
      * 输入事件
      * @param pi
      */
-    void handleInputImp(Transceiver * pTransceiver);
+    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,51 +300,112 @@ 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:
     /*
      * 通信器
      */
     Communicator *         _communicator;
 
+    /**
+     * 是否第一个网络线程
+     */
+    bool 				    _isFirst = false;
+
+    /**
+     * 是否公有的网络线程
+     */
+    bool 				   _public = false;
+
     /**
      * notify
      */
-    FDInfo*                 _notify[MAX_CLIENT_NOTIFYEVENT_NUM];
+    FDInfo*                _notify[MAX_CLIENT_NOTIFYEVENT_NUM];
+
+    /**
+     * schedule
+     */
+    shared_ptr<TC_CoroutineScheduler>  _scheduler;
 
+    /**
+     * 独立的网络线程存在, 线程私有数据
+     */ 
+    ServantProxyThreadData *_pSptd = NULL;
+    
     /*
-     * terminate thread
+     * epoll
      */
-    bool                   _terminate;
+    TC_Epoller *_epoller = NULL;
 
     /**
-     * terminate fd info
+     * lock
      */
-    FDInfo                 _terminateFDInfo;
+    TC_ThreadRecMutex              _objectMutex;
 
-	/*
-     * epoll
+	/**
+	 * 保存已创建的objectproxy
+	 */
+    unordered_map<string, ObjectProxy*>    _objectProxys;
+
+    /**
+     * _vObjectProxys读写锁
      */
-    TC_Epoller             _ep;
+	TC_ThreadRWLocker              	_vObjectMutex;
 
-    /*
-     * 下次检查超时的时间
+    /**
+     * 保存已经创建的obj 取的时候可以不用加锁
      */
-    int64_t                _nextTime;
+    vector<ObjectProxy *>       	_vObjectProxys;
 
-    /*
-     * 下次上报数据的时间
+    /**
+     * 读写锁
      */
-    int64_t                _nextStatTime;
+	TC_ThreadRWLocker              	_servantMutex;
+
+    /**
+     * servant对应的objectProxy
+     */
+    unordered_map<ServantProxy*, ObjectProxy*>  _servantObjectProxy;
 
     /*
-     * ObjectProxy的工厂类
+     *保存已经创建obj的数量
      */
-    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;
 };
 
 /////////////////////////////////////////////////////////////////////////////////////

+ 3 - 3
servant/servant/Cookie.h

@@ -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;
         }
     }
 };

+ 0 - 704
servant/servant/CoroutineScheduler.h

@@ -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

+ 49 - 7
servant/servant/Current.h

@@ -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;
 };
 //////////////////////////////////////////////////////////////
 }

+ 32 - 88
servant/servant/EndpointInfo.h

@@ -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
+     */
+	inline bool isTcp() const { return _ep.isTcp(); }
 
     /**
      *
      * @return
      */
-	bool isTcp() const;
+	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(); }
-
-//    /**
-//     * 获取主机地址
-//     *
-//     * @return const struct sockaddr_in&
-//     */
-//    const struct sockaddr_in& addr() const;
+    inline unsigned int getWeightType() const { return _ep.getWeightType(); }
 
-    /**
-     * 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;
 };
 /////////////////////////////////////////////////////////////////////////////
 }

+ 27 - 7
servant/servant/EndpointManager.h

@@ -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;
 
     /*
      * 活跃的结点

+ 38 - 58
servant/servant/Global.h

@@ -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

+ 88 - 103
servant/servant/Message.h

@@ -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
+    bool                        bFromRpc        = false;       //是否是第三方协议的rcp_call,缺省为false
+    RequestPacket               request;        //请求消息体
+    shared_ptr<ResponsePacket>  response;       //响应消息体
+	shared_ptr<TC_NetWorkBuffer::Buffer> sReqData;       //请求消息体
     ServantProxyCallbackPtr     callback;       //异步调用时的回调对象
+    ServantProxy                *proxy          = NULL;
+    ObjectProxy                 *pObjectProxy   = NULL;  //调用端的proxy对象
+    AdapterProxy                *adapter        = NULL;       //调用的adapter
 
-    ServantProxy *              proxy;          //调用的ServantProxy对象
-    ObjectProxy *               pObjectProxy;   //调用端的proxy对象
+	ReqMonitor                  *pMonitor       = NULL;      //用于同步的monitor
 
-    RequestPacket               request;        //请求消息体
-    std::function<void()>       deconstructor;  //析构时调用
-    shared_ptr<ResponsePacket>      response;   //响应消息体
-    // string                      sReqData;       //请求消息体
-	shared_ptr<TC_NetWorkBuffer::Buffer> sReqData;       //请求消息体
+    int64_t                     iBeginTime      = 0;     //请求时间
+    int64_t                     iEndTime        = 0;       //完成时间
 
-	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
+    bool                        bPush           = false;          //push back 消息
 
-    bool                        bDyeing;        //是否需要染色
-    string                      sDyeingKey;     //染色key
+    bool                        bTraceCall;     // 是否需要调用链追踪
+    string                      sTraceKey;      // 调用链key
 
-    bool                        bPush;          //push back 消息
+    shared_ptr<TC_CoroutineScheduler>      sched;
+    int                         iCoroId         = 0;
 
-    bool						bCoroFlag;
+    std::function<void()>       deconstructor;  //析构时调用
 
-    CoroutineScheduler          *sched;
+    ThreadPrivateData           data;     //线程数据
+};
 
-    uint32_t					iCoroId;
+/**
+ * 用于同步调用时的条件变量
+ */
+struct ReqMonitor
+{
+	ReqMessage 				*msg = NULL;
+	std::mutex 				mutex;
+	std::condition_variable cond;
+	bool               		bMonitorFin     = false;    //同步请求timewait是否结束
 
-    map<string, string>         cookie;          // cookie内容
+	ReqMonitor(ReqMessage *m) : msg(m) {}
 
-    std::unordered_map<std::string, std::string> trackInfoMap; //调用链信息
+	void wait();
+	void notify();
 };
 
 typedef TC_AutoPtr<ReqMessage>  ReqMessagePtr;

+ 0 - 38
servant/servant/NetworkUtil.h

@@ -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

+ 21 - 152
servant/servant/ObjectProxy.h

@@ -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;
 
     /*
      * 超时队列(连接建立前)

+ 0 - 190
servant/servant/ProxyInfo.h

@@ -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

+ 127 - 54
servant/servant/RemoteLogger.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; \
+    }
+//////////////////////////////////////////////
 
 /**
  *  按天日志局部使能开关,针对单个日志文件进行使能,请在所有按天日志输出前调用

+ 0 - 1
servant/servant/Servant.h

@@ -28,7 +28,6 @@
 namespace tars
 {
 
-class BaseNotify;
 class Application;
 ////////////////////////////////////////////////////////////////////
 /**

+ 26 - 48
servant/servant/ServantHandle.h

@@ -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,33 +137,40 @@ protected:
      *
      * @param current
      */
-    void handleTarsProtocol(const TarsCurrentPtr &current);
+    void handleTarsProtocol(const CurrentPtr &current);
 
     /**
      * 处理非Tars协议
      *
      * @param current
      */
-    void handleNoTarsProtocol(const TarsCurrentPtr &current);
+    void handleNoTarsProtocol(const CurrentPtr &current);
+
+
+// #ifdef TARS_OPENTRACKING
+//     /**
+//      * 处理TARS下的调用链逻辑
+//      *
+//      * @param current
+//      */
+//     void processTracking(const CurrentPtr &current);
 
 
-#ifdef TARS_OPENTRACKING
+//     void finishTracking(int ret, const CurrentPtr &current);
+// #endif
     /**
-     * 处理TARS下的调用链逻辑
+     * 处理TARS下的染色逻辑
      *
      * @param current
      */
-    void processTracking(const TarsCurrentPtr &current);
-
+    bool processDye(const CurrentPtr &current, string& dyeingKey);
 
-    void finishTracking(int ret, const TarsCurrentPtr &current);
-#endif
     /**
-     * 处理TARS下的染色逻辑
+     * 处理TARS下的调用链追踪
      *
      * @param current
      */
-    bool processDye(const CurrentPtr &current, string& dyeingKey);
+    bool processTrace(const CurrentPtr &current);
 
     /**
      * 处理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;

+ 7 - 5
servant/servant/ServantHelper.h

@@ -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);

+ 405 - 98
servant/servant/ServantProxy.h

@@ -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
-     */
-	static void reset();
-
-public:
-    /*
-     * 每个线程跟客户端网络线程通信的队列
+     * 析构通信器时调用
+     * @param communicator
      */
-    ReqInfoQueue * _reqQueue[MAX_CLIENT_THREAD_NUM]; //队列数组
-    bool           _queueInit;                       //是否初始化
-    uint16_t       _reqQNo;                          //请求事件通知的seq
-    size_t         _netSeq;                          //轮训选择网络线程的偏移量
-    int            _netThreadSeq;                     //网络线程发起的请求回到自己的网络线程来处理,其值为网络线程的id
+    static void deconstructor(Communicator *communicator);
 
     /**
-     * hash属性,客户端每次调用都进行设置
-     */
-    bool           _hash;                            //是否普通取模hash
-    bool           _conHash;                          //是否一致性hash
-    int64_t        _hashCode;                        //hash值
+     * move掉
+     */ 
+    ThreadPrivateData move();
 
     /**
-     * 染色信息
+     * 业务发起调用的线程和网络通信器间都有一个队列
      */
-    bool           _dyeing;                          //标识当前线程是否需要染色
-    string         _dyeingKey;                        //染色的key值
+    struct CommunicatorEpollReqQueueInfo
+	{
+		weak_ptr<ReqInfoQueue>	_reqQueue;
+		weak_ptr<CommunicatorEpoll> _communicatorEpoll;
+	};
 
-    /**
-     * 允许客户端设置接口级别的超时时间,包括同步和异步、单向
-     */
-    bool           _hasTimeout;                      //是否设置超时间
-    int            _timeout;                         //超时时间
+	//每发起调用的线程 记录的 公有网络通信器数据
+	//此时业务线程和
+	struct CommunicatorEpollInfo
+	{
+		/*
+		 * 每个线程跟客户端网络线程通信的队列
+		 * <网络线程序号, 网络通信信息>
+		 */
+		vector<CommunicatorEpollReqQueueInfo> _info;
+		size_t         _netSeq = 0;                             //轮训选择网络线程的偏移量
+		Communicator   *_communicator = NULL;
+	};
 
-    /**
-     * 保存调用后端服务的地址信息
-     */
-    string           _szHost;                       //调用对端地址
+	/**
+	 * 业务线程处于协程模式下, 记录当前网络通信器信息
+	 * 此时业务线程和网络通信器是一对一的, 即用自身线程对应的私有网络通信器即可
+	 */
+	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:
+	//lock
+	TC_ThreadMutex _mutex;
+
+	//业务线程的序号, 通知网络线程时, 知道用哪个notify来唤醒网路线程
+    uint16_t       _reqQNo;
 
     /**
      * 协程调度
      */
-    CoroutineScheduler*        _sched;                   //协程调度器
+    shared_ptr<TC_CoroutineScheduler>  _sched;
 
-    /**
-     * ObjectProxy
-     */
-    size_t         _objectProxyNum;                  //ObjectProxy对象的个数,其个数由客户端的网络线程数决定,每个网络线程有一个ObjectProxy
+	/**
+	 * 线程私有数据
+	 */
+	ThreadPrivateData       _data;
+
+	/**
+	 * 当前线程是否关联了网络通信器, 如果关联了, 则表示当前线程处于网络线程中!
+	 */
+	CommunicatorEpoll   	*_communicatorEpoll = NULL;
 
+    ///////////////////////////////////////////////////////////////////////////////////////
     /**
-     *  objectProxy Pointer
+     * 调用链追踪信息
      */
-    shared_ptr<ObjectProxy *> _objectProxyOwn;                    //保存ObjectProxy对象的指针数组
+    struct  TraceContext
+    {
+        int    traceType;       // 0 不用打参数, 1 只打客户端调用参数, 2 客户端服务端参数都打印
+        string traceID;         // traceID
+        string spanID;          // spanID
+        string parentSpanID;    // 父spanID
 
+        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;
 
 };
 }

+ 10 - 67
servant/servant/StatReport.h

@@ -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;    
 
 };

+ 0 - 413
servant/servant/Transceiver.h

@@ -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

+ 536 - 137
servant/tup/Tars.h

@@ -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);
-		*/
 	}
 };
 ////////////////////////////////////////////////////////////////////////////////////////////////////

+ 0 - 57
servant/tup/tup.h

@@ -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);
-    // }
 };
 
 /////////////////////////////////////////////////////////////////////////////////

+ 1 - 1
tools/tars2android/main.cpp

@@ -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);

+ 2 - 2
tools/tars2android/tars2android.h

@@ -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;

+ 3 - 3
util/include/util/tc_coroutine.h

@@ -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);
 
     /**
      * 当前协程自己放弃执行,会自动被调度器唤醒

+ 23 - 3
util/include/util/tc_epoll_server.h

@@ -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;

+ 2 - 2
util/include/util/tc_logger.h

@@ -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
 		{

+ 3 - 3
util/include/util/tc_mysql.h

@@ -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 定义字段类型, 

+ 1 - 1
util/include/util/tc_network_buffer.h

@@ -1053,4 +1053,4 @@ protected:
 
 }
 
-#endif //TAF_CPP_TC_NETWORKBUFFER_H
+#endif //TARS_CPP_TC_NETWORKBUFFER_H

+ 1 - 1
util/include/util/tc_openssl.h

@@ -218,7 +218,7 @@ public:
 
 #endif
 
-} // end namespace taf
+} // end namespace tars
 
 
 

+ 13 - 9
util/include/util/tc_port.h

@@ -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;
 };
 
 }

+ 1 - 1
util/include/util/tc_proxy_info.h

@@ -277,4 +277,4 @@ public:
 
 }
 
-#endif //TAF_CPP_PROXYINFO_H
+#endif //TARS_CPP_PROXYINFO_H

+ 1 - 1
util/include/util/tc_thread.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即可启动线程

+ 1 - 1
util/include/util/tc_thread_cond.h

@@ -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
  */             

+ 1 - 1
util/include/util/tc_thread_mutex.h

@@ -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  
  */

+ 4 - 1
util/include/util/tc_uuid_generator.h

@@ -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

+ 4 - 4
util/src/tc_coroutine.cpp

@@ -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()

+ 23 - 35
util/src/tc_epoll_server.cpp

@@ -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,47 +735,35 @@ TC_NetWorkBuffer::PACKET_TYPE TC_EpollServer::Connection::onParserCallback(TC_Ne
 	return ret;
 }
 
+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, length));
+	}
+
+	return 0;
+}
 
 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(std::make_shared<TC_NetWorkBuffer::Buffer>(buff.data(), buff.length()));
+		return _trans->sendRequest(buff);
 	}
 
 	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::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

+ 9 - 6
util/src/tc_grpc.cpp

@@ -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;

+ 2 - 2
util/src/tc_http_async.cpp

@@ -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, "");

+ 2 - 2
util/src/tc_mysql.cpp

@@ -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++;
     }
 

+ 22 - 19
util/src/tc_port.cpp

@@ -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;
 						   }

+ 1 - 1
util/src/tc_thread.cpp

@@ -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);

+ 8 - 8
util/src/tc_transceiver.cpp

@@ -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)

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.