Compare commits

...

33 Commits

Author SHA1 Message Date
boyce
eebbef52c9 优化重复启动验证 2024-03-08 10:32:32 +08:00
boyce
2ddc54f5ac 优化node启动 2024-03-05 17:38:02 +08:00
boyce
75ef7302de Merge branch 'master' of https://github.com/duanhf2012/origin 2024-03-01 17:47:08 +08:00
boyce
ecea9d1706 优化进程启动 2024-03-01 17:35:32 +08:00
boyce
4898116698 优化concurrent,禁止重复打开 2024-02-27 16:18:51 +08:00
boyce
bcbee6dd11 优化readme 2023-11-20 13:32:34 +08:00
duanhf2012
43122190a3 补充新增GetNodeInfo接口 2023-11-15 08:48:41 +08:00
duanhf2012
39b862e3d9 新增IsNodeRetire函数,用于判断NodeId是否为Retire状态 2023-10-09 16:57:05 +08:00
duanhf2012
8c9b796fce 优化日志输出 2023-10-09 16:50:09 +08:00
duanhf2012
c0971a46a7 新增retire命令参数用于将置于服务退休状态,使得服务软关闭 2023-10-09 15:27:01 +08:00
duanhf2012
ba019ac466 优化服务发现README文档 2023-09-24 13:53:18 +08:00
duanhf2012
c803b9b9ad 优化tcpservice 2023-09-22 16:29:31 +08:00
duanhf2012
3f52ea8331 优化筛选服务发现---支持对指定主master结点进行筛选 2023-09-22 15:43:41 +08:00
duanhf2012
2d1bee4dea 优化日志输出格式 2023-09-01 17:44:59 +08:00
duanhf2012
fa8cbfb40e 优化rpc处理异常问题 2023-08-29 18:23:20 +08:00
duanhf2012
388b946401 优化日志的ErrorAttr 2023-08-24 11:34:43 +08:00
duanhf2012
582a0faa6f 替换gogoprotobuf为google标准库 2023-08-21 15:44:55 +08:00
duanhf2012
fa6039e2cb 优化异步日志 2023-08-17 15:54:36 +08:00
duanhf2012
25a672ca53 新增优化异步日志 2023-08-17 15:35:22 +08:00
duanhf2012
75f881be28 新增异步日志功能 2023-08-17 14:00:36 +08:00
duanhf2012
ef8182eec7 替换日志库为slog 2023-08-15 15:46:38 +08:00
duanhf2012
4ad8204fde 优化module包的名称 2023-08-04 17:21:23 +08:00
duanhf2012
8f15546fb1 整理README格式 2023-08-01 11:12:54 +08:00
duanhf2012
0f3a965d73 补充与优化rpc超时功能RAEDME说明 2023-08-01 11:05:51 +08:00
duanhf2012
dfb6959843 优化消息队列默认超时推送时间 2023-07-28 17:43:39 +08:00
duanhf2012
dd4aaf9c57 优化rpc超时 2023-07-28 17:38:52 +08:00
duanhf2012
6ef98a2104 优化新增Rpc压缩与自定义超时功能 2023-07-25 17:36:47 +08:00
duanhf2012
1890b300ee 优化新增rpc压缩功能 2023-07-25 15:13:58 +08:00
duanhf2012
6fea2226e1 优化协议解析器 2023-07-21 17:03:15 +08:00
duanhf2012
ec1c2b4517 node支持rpc压缩 2023-07-21 15:28:52 +08:00
duanhf2012
4b84d9a1d5 新增rpc自定义超时 2023-07-13 16:42:23 +08:00
duanhf2012
85a8ec58e5 rpc加入压缩功能 2023-07-10 14:22:23 +08:00
duanhf2012
962016d476 优化rpc 2023-07-07 13:50:57 +08:00
62 changed files with 4381 additions and 9783 deletions

View File

@@ -19,7 +19,7 @@ Hello world!
```go ```go
go get -v -u github.com/duanhf2012/origin go get -v -u github.com/duanhf2012/origin
``` ```
[README.md](README.md)
于是下载到GOPATH环境目录中,在src中加入main.go,内容如下: 于是下载到GOPATH环境目录中,在src中加入main.go,内容如下:
```go ```go
@@ -64,17 +64,19 @@ cluster.json如下
"Private": false, "Private": false,
"ListenAddr":"127.0.0.1:8001", "ListenAddr":"127.0.0.1:8001",
"MaxRpcParamLen": 409600, "MaxRpcParamLen": 409600,
"CompressBytesLen": 20480,
"NodeName": "Node_Test1", "NodeName": "Node_Test1",
"remark":"//以_打头的表示只在本机进程不对整个子网公开", "remark":"//以_打头的表示只在本机进程不对整个子网公开",
"ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","_TcpService","HttpService","WSService"] "ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","_TcpService","HttpService","WSService"]
}, },
{ {
"NodeId": 2, "NodeId": 2,
"Private": false, "Private": false,
"ListenAddr":"127.0.0.1:8002", "ListenAddr":"127.0.0.1:8002",
"MaxRpcParamLen": 409600, "MaxRpcParamLen": 409600,
"CompressBytesLen": 20480,
"NodeName": "Node_Test1", "NodeName": "Node_Test1",
"remark":"//以_打头的表示只在本机进程不对整个子网公开", "remark":"//以_打头的表示只在本机进程不对整个子网公开",
"ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","TcpService","HttpService","WSService"] "ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","TcpService","HttpService","WSService"]
} }
] ]
@@ -88,6 +90,7 @@ cluster.json如下
* Private: 是否私有结点如果为true表示其他结点不会发现它但可以自我运行。 * Private: 是否私有结点如果为true表示其他结点不会发现它但可以自我运行。
* ListenAddr:Rpc通信服务的监听地址 * ListenAddr:Rpc通信服务的监听地址
* MaxRpcParamLen:Rpc参数数据包最大长度该参数可以缺省默认一次Rpc调用支持最大4294967295byte长度数据。 * MaxRpcParamLen:Rpc参数数据包最大长度该参数可以缺省默认一次Rpc调用支持最大4294967295byte长度数据。
* CompressBytesLen:Rpc网络数据压缩当数据>=20480byte时将被压缩。该参数可以缺省或者填0时不进行压缩。
* NodeName:结点名称 * NodeName:结点名称
* remark:备注,可选项 * remark:备注,可选项
* ServiceList:该Node拥有的服务列表注意origin按配置的顺序进行安装初始化。但停止服务的顺序是相反。 * ServiceList:该Node拥有的服务列表注意origin按配置的顺序进行安装初始化。但停止服务的顺序是相反。
@@ -715,6 +718,15 @@ func (slf *TestService7) CallTest(){
}else{ }else{
fmt.Printf("Call output %d\n",output) fmt.Printf("Call output %d\n",output)
} }
//自定义超时,默认rpc超时时间为15s
err = slf.CallWithTimeout(time.Second*1, "TestService6.RPC_Sum", &input, &output)
if err != nil {
fmt.Printf("Call error :%+v\n", err)
} else {
fmt.Printf("Call output %d\n", output)
}
} }
@@ -726,13 +738,27 @@ func (slf *TestService7) AsyncCallTest(){
})*/ })*/
//异步调用,在数据返回时,会回调传入函数 //异步调用,在数据返回时,会回调传入函数
//注意函数的第一个参数一定是RPC_Sum函数的第二个参数err error为RPC_Sum返回值 //注意函数的第一个参数一定是RPC_Sum函数的第二个参数err error为RPC_Sum返回值
slf.AsyncCall("TestService6.RPC_Sum",&input,func(output *int,err error){ err := slf.AsyncCall("TestService6.RPC_Sum", &input, func(output *int, err error) {
if err != nil { if err != nil {
fmt.Printf("AsyncCall error :%+v\n",err) fmt.Printf("AsyncCall error :%+v\n", err)
}else{ } else {
fmt.Printf("AsyncCall output %d\n",*output) fmt.Printf("AsyncCall output %d\n", *output)
} }
}) })
fmt.Println(err)
//自定义超时,返回一个cancel函数可以在业务需要时取消rpc调用
rpcCancel, err := slf.AsyncCallWithTimeout(time.Second*1, "TestService6.RPC_Sum", &input, func(output *int, err error) {
//如果下面注释的rpcCancel()函数被调用,这里可能将不再返回
if err != nil {
fmt.Printf("AsyncCall error :%+v\n", err)
} else {
fmt.Printf("AsyncCall output %d\n", *output)
}
})
//rpcCancel()
fmt.Println(err, rpcCancel)
} }
func (slf *TestService7) GoTest(){ func (slf *TestService7) GoTest(){
@@ -832,8 +858,7 @@ origin引擎默认使用读取所有结点配置的进行确认结点有哪些Se
"MasterDiscoveryNode": [{ "MasterDiscoveryNode": [{
"NodeId": 2, "NodeId": 2,
"ListenAddr": "127.0.0.1:10001", "ListenAddr": "127.0.0.1:10001",
"MaxRpcParamLen": 409600, "MaxRpcParamLen": 409600
"NeighborService":["HttpGateService"]
}, },
{ {
"NodeId": 1, "NodeId": 1,
@@ -850,17 +875,18 @@ origin引擎默认使用读取所有结点配置的进行确认结点有哪些Se
"Private": false, "Private": false,
"remark": "//以_打头的表示只在本机进程不对整个子网开发", "remark": "//以_打头的表示只在本机进程不对整个子网开发",
"ServiceList": ["_TestService1", "TestService9", "TestService10"], "ServiceList": ["_TestService1", "TestService9", "TestService10"],
"DiscoveryService": ["TestService8"] "MasterDiscoveryService": [
{
"MasterNodeId": 2,
"DiscoveryService": ["TestService8"]
}
]
}] }]
} }
``` ```
MasterDiscoveryNode: 配置了结点Id为1的服务发现Master他的监听地址ListenAddr为127.0.0.1:8801结点为2的也是一个服务发现Master。NodeId为1的结点会从结点为1和2的网络中发现服务。
新上有两新不同的字段分别为MasterDiscoveryNode与DiscoveryService。其中: MasterDiscoveryService: 表示将筛选origin网络中MasterNodeId为2中的TestService8服务注意如果MasterDiscoveryService不配置则筛选功能不生效。MasterNodeId也可以填为0表示NodeId为1的结点在所有网络中只发现TestService8的服务。
MasterDiscoveryNode中配置了结点Id为1的服务发现Master他的监听地址ListenAddr为127.0.0.1:8801结点为2的也是一个服务发现Master不同在于多了"NeighborService":["HttpGateService"]配置。如果"NeighborService"有配置具体的服务时则表示该结点是一个邻居Master结点。当前运行的Node结点会从该Master结点上筛选HttpGateService的服务并且当前运行的Node结点不会向上同步本地所有公开的服务和邻居结点关系是单向的。
NeighborService可以用在当有多个以Master中心结点的网络发现跨网络的服务场景。
DiscoveryService表示将筛选origin网络中的TestService8服务注意如果DiscoveryService不配置则筛选功能不生效。
第八章HttpService使用 第八章HttpService使用
----------------------- -----------------------
@@ -1036,7 +1062,7 @@ func (slf *TestTcpService) OnRequest (clientid uint64,msg proto.Message){
提交bug及特性: https://github.com/duanhf2012/origin/issues 提交bug及特性: https://github.com/duanhf2012/origin/issues
[因服务器是由个人维护,如果这个项目对您有帮助,您可以点我进行捐赠,感谢!](http://www.cppblog.com/images/cppblog_com/API/21416/r_pay.jpg "Thanks!") [因服务器是由个人维护,如果这个项目对您有帮助,您可以点我进行捐赠,感谢!](http://www.cppblog.com/images/cppblog_com/API/21416/r_pay.jpg "Thanks!")
![](http://www.cppblog.com/images/cppblog_com/API/21416/r_pay.jpg)
特别感谢以下赞助网友: 特别感谢以下赞助网友:
``` ```
@@ -1045,4 +1071,5 @@ _
死磕代码 死磕代码
bp-li bp-li
阿正 阿正
大头
``` ```

View File

@@ -20,17 +20,23 @@ const (
Discard NodeStatus = 1 //丢弃 Discard NodeStatus = 1 //丢弃
) )
type MasterDiscoveryService struct {
MasterNodeId int32 //要筛选的主结点Id如果不配置或者配置成0表示针对所有的主结点
DiscoveryService []string //只发现的服务列表
}
type NodeInfo struct { type NodeInfo struct {
NodeId int NodeId int
NodeName string NodeName string
Private bool Private bool
ListenAddr string ListenAddr string
MaxRpcParamLen uint32 //最大Rpc参数长度 MaxRpcParamLen uint32 //最大Rpc参数长度
CompressBytesLen int //超过字节进行压缩的长度
ServiceList []string //所有的有序服务列表 ServiceList []string //所有的有序服务列表
PublicServiceList []string //对外公开的服务列表 PublicServiceList []string //对外公开的服务列表
DiscoveryService []string //筛选发现的服务,如果不配置,不进行筛选 MasterDiscoveryService []MasterDiscoveryService //筛选发现的服务,如果不配置,不进行筛选
NeighborService []string
status NodeStatus status NodeStatus
Retire bool
} }
type NodeRpcInfo struct { type NodeRpcInfo struct {
@@ -50,8 +56,8 @@ type Cluster struct {
locker sync.RWMutex //结点与服务关系保护锁 locker sync.RWMutex //结点与服务关系保护锁
mapRpc map[int]NodeRpcInfo //nodeId mapRpc map[int]*NodeRpcInfo //nodeId
mapIdNode map[int]NodeInfo //map[NodeId]NodeInfo //mapIdNode map[int]NodeInfo //map[NodeId]NodeInfo
mapServiceNode map[string]map[int]struct{} //map[serviceName]map[NodeId] mapServiceNode map[string]map[int]struct{} //map[serviceName]map[NodeId]
rpcServer rpc.Server rpcServer rpc.Server
@@ -73,7 +79,7 @@ func SetServiceDiscovery(serviceDiscovery IServiceDiscovery) {
} }
func (cls *Cluster) Start() { func (cls *Cluster) Start() {
cls.rpcServer.Start(cls.localNodeInfo.ListenAddr, cls.localNodeInfo.MaxRpcParamLen) cls.rpcServer.Start(cls.localNodeInfo.ListenAddr, cls.localNodeInfo.MaxRpcParamLen,cls.localNodeInfo.CompressBytesLen)
} }
func (cls *Cluster) Stop() { func (cls *Cluster) Stop() {
@@ -82,10 +88,11 @@ func (cls *Cluster) Stop() {
func (cls *Cluster) DiscardNode(nodeId int) { func (cls *Cluster) DiscardNode(nodeId int) {
cls.locker.Lock() cls.locker.Lock()
nodeInfo, ok := cls.mapIdNode[nodeId] nodeInfo, ok := cls.mapRpc[nodeId]
bDel := (ok == true) && nodeInfo.nodeInfo.status == Discard
cls.locker.Unlock() cls.locker.Unlock()
if ok == true && nodeInfo.status == Discard { if bDel {
cls.DelNode(nodeId, true) cls.DelNode(nodeId, true)
} }
} }
@@ -98,39 +105,30 @@ func (cls *Cluster) DelNode(nodeId int, immediately bool) {
cls.locker.Lock() cls.locker.Lock()
defer cls.locker.Unlock() defer cls.locker.Unlock()
nodeInfo, ok := cls.mapIdNode[nodeId] rpc, ok := cls.mapRpc[nodeId]
if ok == false { if ok == false {
return return
} }
rpc, ok := cls.mapRpc[nodeId] if immediately ==false {
for {
//立即删除
if immediately || ok == false {
break
}
//正在连接中不主动断开,只断开没有连接中的 //正在连接中不主动断开,只断开没有连接中的
if rpc.client.IsConnected() { if rpc.client.IsConnected() {
nodeInfo.status = Discard rpc.nodeInfo.status = Discard
log.SRelease("Discard node ", nodeInfo.NodeId, " ", nodeInfo.ListenAddr) log.Info("Discard node",log.Int("nodeId",rpc.nodeInfo.NodeId),log.String("ListenAddr", rpc.nodeInfo.ListenAddr))
return return
} }
break
} }
for _, serviceName := range nodeInfo.ServiceList { for _, serviceName := range rpc.nodeInfo.ServiceList {
cls.delServiceNode(serviceName, nodeId) cls.delServiceNode(serviceName, nodeId)
} }
delete(cls.mapIdNode, nodeId)
delete(cls.mapRpc, nodeId) delete(cls.mapRpc, nodeId)
if ok == true { if ok == true {
rpc.client.Close(false) rpc.client.Close(false)
} }
log.SRelease("remove node ", nodeInfo.NodeId, " ", nodeInfo.ListenAddr) log.Info("remove node ",log.Int("NodeId", rpc.nodeInfo.NodeId),log.String("ListenAddr", rpc.nodeInfo.ListenAddr))
} }
func (cls *Cluster) serviceDiscoveryDelNode(nodeId int, immediately bool) { func (cls *Cluster) serviceDiscoveryDelNode(nodeId int, immediately bool) {
@@ -163,9 +161,9 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
defer cls.locker.Unlock() defer cls.locker.Unlock()
//先清一次的NodeId对应的所有服务清理 //先清一次的NodeId对应的所有服务清理
lastNodeInfo, ok := cls.mapIdNode[nodeInfo.NodeId] lastNodeInfo, ok := cls.mapRpc[nodeInfo.NodeId]
if ok == true { if ok == true {
for _, serviceName := range lastNodeInfo.ServiceList { for _, serviceName := range lastNodeInfo.nodeInfo.ServiceList {
cls.delServiceNode(serviceName, nodeInfo.NodeId) cls.delServiceNode(serviceName, nodeInfo.NodeId)
} }
} }
@@ -175,7 +173,7 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
for _, serviceName := range nodeInfo.PublicServiceList { for _, serviceName := range nodeInfo.PublicServiceList {
if _, ok := mapDuplicate[serviceName]; ok == true { if _, ok := mapDuplicate[serviceName]; ok == true {
//存在重复 //存在重复
log.SError("Bad duplicate Service Cfg.") log.Error("Bad duplicate Service Cfg.")
continue continue
} }
mapDuplicate[serviceName] = nil mapDuplicate[serviceName] = nil
@@ -184,28 +182,22 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
} }
cls.mapServiceNode[serviceName][nodeInfo.NodeId] = struct{}{} cls.mapServiceNode[serviceName][nodeInfo.NodeId] = struct{}{}
} }
cls.mapIdNode[nodeInfo.NodeId] = *nodeInfo
log.SRelease("Discovery nodeId: ", nodeInfo.NodeId, " services:", nodeInfo.PublicServiceList) if lastNodeInfo != nil {
log.Info("Discovery nodeId",log.Int("NodeId", nodeInfo.NodeId),log.Any("services:", nodeInfo.PublicServiceList),log.Bool("Retire",nodeInfo.Retire))
//已经存在连接,则不需要进行设置 lastNodeInfo.nodeInfo = *nodeInfo
if _, rpcInfoOK := cls.mapRpc[nodeInfo.NodeId]; rpcInfoOK == true {
return return
} }
//不存在时,则建立连接
rpcInfo := NodeRpcInfo{} rpcInfo := NodeRpcInfo{}
rpcInfo.nodeInfo = *nodeInfo rpcInfo.nodeInfo = *nodeInfo
rpcInfo.client =rpc.NewRClient(nodeInfo.NodeId, nodeInfo.ListenAddr, nodeInfo.MaxRpcParamLen,cls.triggerRpcEvent) rpcInfo.client =rpc.NewRClient(nodeInfo.NodeId, nodeInfo.ListenAddr, nodeInfo.MaxRpcParamLen,cls.localNodeInfo.CompressBytesLen,cls.triggerRpcEvent)
cls.mapRpc[nodeInfo.NodeId] = rpcInfo cls.mapRpc[nodeInfo.NodeId] = &rpcInfo
log.Info("Discovery nodeId and new rpc client",log.Int("NodeId", nodeInfo.NodeId),log.Any("services:", nodeInfo.PublicServiceList),log.Bool("Retire",nodeInfo.Retire),log.String("nodeListenAddr",nodeInfo.ListenAddr))
} }
func (cls *Cluster) buildLocalRpc() {
rpcInfo := NodeRpcInfo{}
rpcInfo.nodeInfo = cls.localNodeInfo
rpcInfo.client = rpc.NewLClient(rpcInfo.nodeInfo.NodeId)
cls.mapRpc[cls.localNodeInfo.NodeId] = rpcInfo
}
func (cls *Cluster) Init(localNodeId int, setupServiceFun SetupServiceFun) error { func (cls *Cluster) Init(localNodeId int, setupServiceFun SetupServiceFun) error {
//1.初始化配置 //1.初始化配置
@@ -215,7 +207,6 @@ func (cls *Cluster) Init(localNodeId int, setupServiceFun SetupServiceFun) error
} }
cls.rpcServer.Init(cls) cls.rpcServer.Init(cls)
cls.buildLocalRpc()
//2.安装服务发现结点 //2.安装服务发现结点
cls.SetupServiceDiscovery(localNodeId, setupServiceFun) cls.SetupServiceDiscovery(localNodeId, setupServiceFun)
@@ -309,27 +300,33 @@ func (cls *Cluster) FindRpcHandler(serviceName string) rpc.IRpcHandler {
return pService.GetRpcHandler() return pService.GetRpcHandler()
} }
func (cls *Cluster) getRpcClient(nodeId int) *rpc.Client { func (cls *Cluster) getRpcClient(nodeId int) (*rpc.Client,bool) {
c, ok := cls.mapRpc[nodeId] c, ok := cls.mapRpc[nodeId]
if ok == false { if ok == false {
return nil return nil,false
} }
return c.client return c.client,c.nodeInfo.Retire
} }
func (cls *Cluster) GetRpcClient(nodeId int) *rpc.Client { func (cls *Cluster) GetRpcClient(nodeId int) (*rpc.Client,bool) {
cls.locker.RLock() cls.locker.RLock()
defer cls.locker.RUnlock() defer cls.locker.RUnlock()
return cls.getRpcClient(nodeId) return cls.getRpcClient(nodeId)
} }
func GetRpcClient(nodeId int, serviceMethod string, clientList []*rpc.Client) (error, int) { func GetRpcClient(nodeId int, serviceMethod string,filterRetire bool, clientList []*rpc.Client) (error, int) {
if nodeId > 0 { if nodeId > 0 {
pClient := GetCluster().GetRpcClient(nodeId) pClient,retire := GetCluster().GetRpcClient(nodeId)
if pClient == nil { if pClient == nil {
return fmt.Errorf("cannot find nodeid %d!", nodeId), 0 return fmt.Errorf("cannot find nodeid %d!", nodeId), 0
} }
//如果需要筛选掉退休结点
if filterRetire == true && retire == true {
return fmt.Errorf("cannot find nodeid %d!", nodeId), 0
}
clientList[0] = pClient clientList[0] = pClient
return nil, 1 return nil, 1
} }
@@ -341,7 +338,7 @@ func GetRpcClient(nodeId int, serviceMethod string, clientList []*rpc.Client) (e
serviceName := serviceMethod[:findIndex] serviceName := serviceMethod[:findIndex]
//1.找到对应的rpcNodeid //1.找到对应的rpcNodeid
return GetCluster().GetNodeIdByService(serviceName, clientList, true) return GetCluster().GetNodeIdByService(serviceName, clientList, filterRetire)
} }
func GetRpcServer() *rpc.Server { func GetRpcServer() *rpc.Server {
@@ -349,10 +346,19 @@ func GetRpcServer() *rpc.Server {
} }
func (cls *Cluster) IsNodeConnected(nodeId int) bool { func (cls *Cluster) IsNodeConnected(nodeId int) bool {
pClient := cls.GetRpcClient(nodeId) pClient,_ := cls.GetRpcClient(nodeId)
return pClient != nil && pClient.IsConnected() return pClient != nil && pClient.IsConnected()
} }
func (cls *Cluster) IsNodeRetire(nodeId int) bool {
cls.locker.RLock()
defer cls.locker.RUnlock()
_,retire :=cls.getRpcClient(nodeId)
return retire
}
func (cls *Cluster) triggerRpcEvent(bConnect bool, clientId uint32, nodeId int) { func (cls *Cluster) triggerRpcEvent(bConnect bool, clientId uint32, nodeId int) {
cls.locker.Lock() cls.locker.Lock()
nodeInfo, ok := cls.mapRpc[nodeId] nodeInfo, ok := cls.mapRpc[nodeId]
@@ -367,7 +373,7 @@ func (cls *Cluster) triggerRpcEvent(bConnect bool, clientId uint32, nodeId int)
for serviceName, _ := range cls.mapServiceListenRpcEvent { for serviceName, _ := range cls.mapServiceListenRpcEvent {
ser := service.GetService(serviceName) ser := service.GetService(serviceName)
if ser == nil { if ser == nil {
log.SError("cannot find service name ", serviceName) log.Error("cannot find service name "+serviceName)
continue continue
} }
@@ -385,7 +391,7 @@ func (cls *Cluster) TriggerDiscoveryEvent(bDiscovery bool, nodeId int, serviceNa
for sName, _ := range cls.mapServiceListenDiscoveryEvent { for sName, _ := range cls.mapServiceListenDiscoveryEvent {
ser := service.GetService(sName) ser := service.GetService(sName)
if ser == nil { if ser == nil {
log.SError("cannot find service name ", serviceName) log.Error("cannot find service",log.Any("services",serviceName))
continue continue
} }
@@ -471,11 +477,14 @@ func (cls *Cluster) GetGlobalCfg() interface{} {
return cls.globalCfg return cls.globalCfg
} }
func (cls *Cluster) GetNodeInfo(nodeId int) (NodeInfo,bool) { func (cls *Cluster) GetNodeInfo(nodeId int) (NodeInfo,bool) {
cls.locker.RLock() cls.locker.RLock()
defer cls.locker.RUnlock() defer cls.locker.RUnlock()
nodeInfo,ok:= cls.mapIdNode[nodeId] nodeInfo,ok:= cls.mapRpc[nodeId]
return nodeInfo,ok if ok == false || nodeInfo == nil {
return NodeInfo{},false
}
return nodeInfo.nodeInfo,true
} }

View File

@@ -5,6 +5,9 @@ import (
"github.com/duanhf2012/origin/log" "github.com/duanhf2012/origin/log"
"github.com/duanhf2012/origin/rpc" "github.com/duanhf2012/origin/rpc"
"github.com/duanhf2012/origin/service" "github.com/duanhf2012/origin/service"
"time"
"github.com/duanhf2012/origin/util/timer"
"google.golang.org/protobuf/proto"
) )
const DynamicDiscoveryMasterName = "DiscoveryMaster" const DynamicDiscoveryMasterName = "DiscoveryMaster"
@@ -12,6 +15,7 @@ const DynamicDiscoveryClientName = "DiscoveryClient"
const RegServiceDiscover = DynamicDiscoveryMasterName + ".RPC_RegServiceDiscover" const RegServiceDiscover = DynamicDiscoveryMasterName + ".RPC_RegServiceDiscover"
const SubServiceDiscover = DynamicDiscoveryClientName + ".RPC_SubServiceDiscover" const SubServiceDiscover = DynamicDiscoveryClientName + ".RPC_SubServiceDiscover"
const AddSubServiceDiscover = DynamicDiscoveryMasterName + ".RPC_AddSubServiceDiscover" const AddSubServiceDiscover = DynamicDiscoveryMasterName + ".RPC_AddSubServiceDiscover"
const NodeRetireRpcMethod = DynamicDiscoveryMasterName+".RPC_NodeRetire"
type DynamicDiscoveryMaster struct { type DynamicDiscoveryMaster struct {
service.Service service.Service
@@ -28,6 +32,7 @@ type DynamicDiscoveryClient struct {
localNodeId int localNodeId int
mapDiscovery map[int32]map[int32]struct{} //map[masterNodeId]map[nodeId]struct{} mapDiscovery map[int32]map[int32]struct{} //map[masterNodeId]map[nodeId]struct{}
bRetire bool
} }
var masterService DynamicDiscoveryMaster var masterService DynamicDiscoveryMaster
@@ -47,16 +52,32 @@ func (ds *DynamicDiscoveryMaster) isRegNode(nodeId int32) bool {
return ok return ok
} }
func (ds *DynamicDiscoveryMaster) addNodeInfo(nodeInfo *rpc.NodeInfo) { func (ds *DynamicDiscoveryMaster) updateNodeInfo(nInfo *rpc.NodeInfo) {
if len(nodeInfo.PublicServiceList) == 0 { if _,ok:= ds.mapNodeInfo[nInfo.NodeId];ok == false {
return return
} }
_, ok := ds.mapNodeInfo[nodeInfo.NodeId] nodeInfo := proto.Clone(nInfo).(*rpc.NodeInfo)
for i:=0;i<len(ds.nodeInfo);i++ {
if ds.nodeInfo[i].NodeId == nodeInfo.NodeId {
ds.nodeInfo[i] = nodeInfo
break
}
}
}
func (ds *DynamicDiscoveryMaster) addNodeInfo(nInfo *rpc.NodeInfo) {
if len(nInfo.PublicServiceList) == 0 {
return
}
_, ok := ds.mapNodeInfo[nInfo.NodeId]
if ok == true { if ok == true {
return return
} }
ds.mapNodeInfo[nodeInfo.NodeId] = struct{}{} ds.mapNodeInfo[nInfo.NodeId] = struct{}{}
nodeInfo := proto.Clone(nInfo).(*rpc.NodeInfo)
ds.nodeInfo = append(ds.nodeInfo, nodeInfo) ds.nodeInfo = append(ds.nodeInfo, nodeInfo)
} }
@@ -85,16 +106,14 @@ func (ds *DynamicDiscoveryMaster) OnInit() error {
func (ds *DynamicDiscoveryMaster) OnStart() { func (ds *DynamicDiscoveryMaster) OnStart() {
var nodeInfo rpc.NodeInfo var nodeInfo rpc.NodeInfo
localNodeInfo := cluster.GetLocalNodeInfo() localNodeInfo := cluster.GetLocalNodeInfo()
if localNodeInfo.Private == true {
return
}
nodeInfo.NodeId = int32(localNodeInfo.NodeId) nodeInfo.NodeId = int32(localNodeInfo.NodeId)
nodeInfo.NodeName = localNodeInfo.NodeName nodeInfo.NodeName = localNodeInfo.NodeName
nodeInfo.ListenAddr = localNodeInfo.ListenAddr nodeInfo.ListenAddr = localNodeInfo.ListenAddr
nodeInfo.PublicServiceList = localNodeInfo.PublicServiceList nodeInfo.PublicServiceList = localNodeInfo.PublicServiceList
nodeInfo.MaxRpcParamLen = localNodeInfo.MaxRpcParamLen nodeInfo.MaxRpcParamLen = localNodeInfo.MaxRpcParamLen
nodeInfo.Private = localNodeInfo.Private
nodeInfo.Retire = localNodeInfo.Retire
ds.addNodeInfo(&nodeInfo) ds.addNodeInfo(&nodeInfo)
} }
@@ -136,11 +155,24 @@ func (ds *DynamicDiscoveryMaster) RpcCastGo(serviceMethod string, args interface
} }
} }
func (ds *DynamicDiscoveryMaster) RPC_NodeRetire(req *rpc.NodeRetireReq, res *rpc.Empty) error {
log.Info("node is retire",log.Int32("nodeId",req.NodeInfo.NodeId),log.Bool("retire",req.NodeInfo.Retire))
ds.updateNodeInfo(req.NodeInfo)
var notifyDiscover rpc.SubscribeDiscoverNotify
notifyDiscover.MasterNodeId = int32(cluster.GetLocalNodeInfo().NodeId)
notifyDiscover.NodeInfo = append(notifyDiscover.NodeInfo, req.NodeInfo)
ds.RpcCastGo(SubServiceDiscover, &notifyDiscover)
return nil
}
// 收到注册过来的结点 // 收到注册过来的结点
func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscoverReq, res *rpc.Empty) error { func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscoverReq, res *rpc.Empty) error {
if req.NodeInfo == nil { if req.NodeInfo == nil {
err := errors.New("RPC_RegServiceDiscover req is error.") err := errors.New("RPC_RegServiceDiscover req is error.")
log.SError(err.Error()) log.Error(err.Error())
return err return err
} }
@@ -163,6 +195,8 @@ func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscove
nodeInfo.PublicServiceList = req.NodeInfo.PublicServiceList nodeInfo.PublicServiceList = req.NodeInfo.PublicServiceList
nodeInfo.ListenAddr = req.NodeInfo.ListenAddr nodeInfo.ListenAddr = req.NodeInfo.ListenAddr
nodeInfo.MaxRpcParamLen = req.NodeInfo.MaxRpcParamLen nodeInfo.MaxRpcParamLen = req.NodeInfo.MaxRpcParamLen
nodeInfo.Retire = req.NodeInfo.Retire
//主动删除已经存在的结点,确保先断开,再连接 //主动删除已经存在的结点,确保先断开,再连接
cluster.serviceDiscoveryDelNode(nodeInfo.NodeId, true) cluster.serviceDiscoveryDelNode(nodeInfo.NodeId, true)
@@ -246,15 +280,6 @@ func (dc *DynamicDiscoveryClient) fullCompareDiffNode(masterNodeId int32, mapNod
//订阅发现的服务通知 //订阅发现的服务通知
func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDiscoverNotify) error { func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDiscoverNotify) error {
//整理当前master结点需要筛选的NeighborService
masterDiscoveryNodeInfo := cluster.GetMasterDiscoveryNodeInfo(int(req.MasterNodeId))
mapMasterDiscoveryService := map[string]struct{}{}
if masterDiscoveryNodeInfo != nil {
for i := 0; i < len(masterDiscoveryNodeInfo.NeighborService); i++ {
mapMasterDiscoveryService[masterDiscoveryNodeInfo.NeighborService[i]] = struct{}{}
}
}
mapNodeInfo := map[int32]*rpc.NodeInfo{} mapNodeInfo := map[int32]*rpc.NodeInfo{}
for _, nodeInfo := range req.NodeInfo { for _, nodeInfo := range req.NodeInfo {
//不对本地结点或者不存在任何公开服务的结点 //不对本地结点或者不存在任何公开服务的结点
@@ -269,13 +294,6 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
//遍历所有的公开服务,并筛选之 //遍历所有的公开服务,并筛选之
for _, serviceName := range nodeInfo.PublicServiceList { for _, serviceName := range nodeInfo.PublicServiceList {
//只有存在配置时才做筛选
if len(mapMasterDiscoveryService) > 0 {
if _, ok := mapMasterDiscoveryService[serviceName]; ok == false {
continue
}
}
nInfo := mapNodeInfo[nodeInfo.NodeId] nInfo := mapNodeInfo[nodeInfo.NodeId]
if nInfo == nil { if nInfo == nil {
nInfo = &rpc.NodeInfo{} nInfo = &rpc.NodeInfo{}
@@ -283,6 +301,9 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
nInfo.NodeName = nodeInfo.NodeName nInfo.NodeName = nodeInfo.NodeName
nInfo.ListenAddr = nodeInfo.ListenAddr nInfo.ListenAddr = nodeInfo.ListenAddr
nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen
nInfo.Retire = nodeInfo.Retire
nInfo.Private = nodeInfo.Private
mapNodeInfo[nodeInfo.NodeId] = nInfo mapNodeInfo[nodeInfo.NodeId] = nInfo
} }
@@ -292,7 +313,6 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
//如果为完整同步,则找出差异的结点 //如果为完整同步,则找出差异的结点
var willDelNodeId []int32 var willDelNodeId []int32
//如果不是邻居结点,则做筛选
if req.IsFull == true { if req.IsFull == true {
diffNode := dc.fullCompareDiffNode(req.MasterNodeId, mapNodeInfo) diffNode := dc.fullCompareDiffNode(req.MasterNodeId, mapNodeInfo)
if len(diffNode) > 0 { if len(diffNode) > 0 {
@@ -307,8 +327,7 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
//删除不必要的结点 //删除不必要的结点
for _, nodeId := range willDelNodeId { for _, nodeId := range willDelNodeId {
nodeInfo,_ := cluster.GetNodeInfo(int(nodeId)) cluster.TriggerDiscoveryEvent(false,int(nodeId),nil)
cluster.TriggerDiscoveryEvent(false,int(nodeId),nodeInfo.PublicServiceList)
dc.removeMasterNode(req.MasterNodeId, int32(nodeId)) dc.removeMasterNode(req.MasterNodeId, int32(nodeId))
if dc.findNodeId(nodeId) == false { if dc.findNodeId(nodeId) == false {
dc.funDelService(int(nodeId), false) dc.funDelService(int(nodeId), false)
@@ -317,10 +336,8 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
//设置新结点 //设置新结点
for _, nodeInfo := range mapNodeInfo { for _, nodeInfo := range mapNodeInfo {
dc.addMasterNode(req.MasterNodeId, nodeInfo.NodeId) bSet := dc.setNodeInfo(req.MasterNodeId,nodeInfo)
dc.setNodeInfo(nodeInfo) if bSet == false {
if len(nodeInfo.PublicServiceList) == 0 {
continue continue
} }
@@ -341,6 +358,33 @@ func (dc *DynamicDiscoveryClient) isDiscoverNode(nodeId int) bool {
} }
func (dc *DynamicDiscoveryClient) OnNodeConnected(nodeId int) { func (dc *DynamicDiscoveryClient) OnNodeConnected(nodeId int) {
dc.regServiceDiscover(nodeId)
}
func (dc *DynamicDiscoveryClient) OnRetire(){
dc.bRetire = true
masterNodeList := cluster.GetDiscoveryNodeList()
for i:=0;i<len(masterNodeList);i++{
var nodeRetireReq rpc.NodeRetireReq
nodeRetireReq.NodeInfo = &rpc.NodeInfo{}
nodeRetireReq.NodeInfo.NodeId = int32(cluster.localNodeInfo.NodeId)
nodeRetireReq.NodeInfo.NodeName = cluster.localNodeInfo.NodeName
nodeRetireReq.NodeInfo.ListenAddr = cluster.localNodeInfo.ListenAddr
nodeRetireReq.NodeInfo.MaxRpcParamLen = cluster.localNodeInfo.MaxRpcParamLen
nodeRetireReq.NodeInfo.PublicServiceList = cluster.localNodeInfo.PublicServiceList
nodeRetireReq.NodeInfo.Retire = dc.bRetire
nodeRetireReq.NodeInfo.Private = cluster.localNodeInfo.Private
err := dc.GoNode(int(masterNodeList[i].NodeId),NodeRetireRpcMethod,&nodeRetireReq)
if err!= nil {
log.Error("call "+NodeRetireRpcMethod+" is fail",log.ErrorAttr("err",err))
}
}
}
func (dc *DynamicDiscoveryClient) regServiceDiscover(nodeId int){
nodeInfo := cluster.GetMasterDiscoveryNodeInfo(nodeId) nodeInfo := cluster.GetMasterDiscoveryNodeInfo(nodeId)
if nodeInfo == nil { if nodeInfo == nil {
return return
@@ -352,57 +396,76 @@ func (dc *DynamicDiscoveryClient) OnNodeConnected(nodeId int) {
req.NodeInfo.NodeName = cluster.localNodeInfo.NodeName req.NodeInfo.NodeName = cluster.localNodeInfo.NodeName
req.NodeInfo.ListenAddr = cluster.localNodeInfo.ListenAddr req.NodeInfo.ListenAddr = cluster.localNodeInfo.ListenAddr
req.NodeInfo.MaxRpcParamLen = cluster.localNodeInfo.MaxRpcParamLen req.NodeInfo.MaxRpcParamLen = cluster.localNodeInfo.MaxRpcParamLen
req.NodeInfo.PublicServiceList = cluster.localNodeInfo.PublicServiceList
//MasterDiscoveryNode配置中没有配置NeighborService则同步当前结点所有服务 req.NodeInfo.Retire = dc.bRetire
if len(nodeInfo.NeighborService) == 0 { req.NodeInfo.Private = cluster.localNodeInfo.Private
req.NodeInfo.PublicServiceList = cluster.localNodeInfo.PublicServiceList
} else {
req.NodeInfo.PublicServiceList = append(req.NodeInfo.PublicServiceList, DynamicDiscoveryClientName)
}
//向Master服务同步本Node服务信息 //向Master服务同步本Node服务信息
err := dc.AsyncCallNode(nodeId, RegServiceDiscover, &req, func(res *rpc.Empty, err error) { err := dc.AsyncCallNode(nodeId, RegServiceDiscover, &req, func(res *rpc.Empty, err error) {
if err != nil { if err != nil {
log.SError("call ", RegServiceDiscover, " is fail :", err.Error()) log.Error("call "+RegServiceDiscover+" is fail :"+ err.Error())
dc.AfterFunc(time.Second*3, func(timer *timer.Timer) {
dc.regServiceDiscover(nodeId)
})
return return
} }
}) })
if err != nil { if err != nil {
log.SError("call ", RegServiceDiscover, " is fail :", err.Error()) log.Error("call "+ RegServiceDiscover+" is fail :"+ err.Error())
} }
} }
func (dc *DynamicDiscoveryClient) setNodeInfo(nodeInfo *rpc.NodeInfo) { func (dc *DynamicDiscoveryClient) canDiscoveryService(fromMasterNodeId int32,serviceName string) bool{
if nodeInfo == nil || nodeInfo.Private == true || int(nodeInfo.NodeId) == dc.localNodeId { canDiscovery := true
return
}
//筛选关注的服务 for i:=0;i<len(cluster.GetLocalNodeInfo().MasterDiscoveryService);i++{
localNodeInfo := cluster.GetLocalNodeInfo() masterNodeId := cluster.GetLocalNodeInfo().MasterDiscoveryService[i].MasterNodeId
if len(localNodeInfo.DiscoveryService) > 0 {
var discoverServiceSlice = make([]string, 0, 24) if masterNodeId == fromMasterNodeId || masterNodeId == 0 {
for _, pubService := range nodeInfo.PublicServiceList { canDiscovery = false
for _, discoverService := range localNodeInfo.DiscoveryService {
if pubService == discoverService { for _,discoveryService := range cluster.GetLocalNodeInfo().MasterDiscoveryService[i].DiscoveryService {
discoverServiceSlice = append(discoverServiceSlice, pubService) if discoveryService == serviceName {
return true
} }
} }
} }
nodeInfo.PublicServiceList = discoverServiceSlice
} }
if len(nodeInfo.PublicServiceList) == 0 { return canDiscovery
return }
func (dc *DynamicDiscoveryClient) setNodeInfo(masterNodeId int32,nodeInfo *rpc.NodeInfo) bool{
if nodeInfo == nil || nodeInfo.Private == true || int(nodeInfo.NodeId) == dc.localNodeId {
return false
}
//筛选关注的服务
var discoverServiceSlice = make([]string, 0, 24)
for _, pubService := range nodeInfo.PublicServiceList {
if dc.canDiscoveryService(masterNodeId,pubService) == true {
discoverServiceSlice = append(discoverServiceSlice,pubService)
}
}
if len(discoverServiceSlice) == 0 {
return false
} }
var nInfo NodeInfo var nInfo NodeInfo
nInfo.ServiceList = nodeInfo.PublicServiceList nInfo.ServiceList = discoverServiceSlice
nInfo.PublicServiceList = nodeInfo.PublicServiceList nInfo.PublicServiceList = discoverServiceSlice
nInfo.NodeId = int(nodeInfo.NodeId) nInfo.NodeId = int(nodeInfo.NodeId)
nInfo.NodeName = nodeInfo.NodeName nInfo.NodeName = nodeInfo.NodeName
nInfo.ListenAddr = nodeInfo.ListenAddr nInfo.ListenAddr = nodeInfo.ListenAddr
nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen
nInfo.Retire = nodeInfo.Retire
nInfo.Private = nodeInfo.Private
dc.funSetService(&nInfo) dc.funSetService(&nInfo)
return true
} }
func (dc *DynamicDiscoveryClient) OnNodeDisconnect(nodeId int) { func (dc *DynamicDiscoveryClient) OnNodeDisconnect(nodeId int) {

View File

@@ -58,7 +58,7 @@ func (cls *Cluster) readServiceConfig(filepath string) (interface{}, map[string]
serviceCfg := v.(map[string]interface{}) serviceCfg := v.(map[string]interface{})
nodeId, ok := serviceCfg["NodeId"] nodeId, ok := serviceCfg["NodeId"]
if ok == false { if ok == false {
log.SFatal("NodeService list not find nodeId field") log.Fatal("NodeService list not find nodeId field")
} }
mapNodeService[int(nodeId.(float64))] = serviceCfg mapNodeService[int(nodeId.(float64))] = serviceCfg
} }
@@ -199,7 +199,11 @@ func (cls *Cluster) readLocalService(localNodeId int) error {
} }
func (cls *Cluster) parseLocalCfg() { func (cls *Cluster) parseLocalCfg() {
cls.mapIdNode[cls.localNodeInfo.NodeId] = cls.localNodeInfo rpcInfo := NodeRpcInfo{}
rpcInfo.nodeInfo = cls.localNodeInfo
rpcInfo.client = rpc.NewLClient(rpcInfo.nodeInfo.NodeId)
cls.mapRpc[cls.localNodeInfo.NodeId] = &rpcInfo
for _, sName := range cls.localNodeInfo.ServiceList { for _, sName := range cls.localNodeInfo.ServiceList {
if _, ok := cls.mapServiceNode[sName]; ok == false { if _, ok := cls.mapServiceNode[sName]; ok == false {
@@ -225,8 +229,7 @@ func (cls *Cluster) checkDiscoveryNodeList(discoverMasterNode []NodeInfo) bool {
func (cls *Cluster) InitCfg(localNodeId int) error { func (cls *Cluster) InitCfg(localNodeId int) error {
cls.localServiceCfg = map[string]interface{}{} cls.localServiceCfg = map[string]interface{}{}
cls.mapRpc = map[int]NodeRpcInfo{} cls.mapRpc = map[int]*NodeRpcInfo{}
cls.mapIdNode = map[int]NodeInfo{}
cls.mapServiceNode = map[string]map[int]struct{}{} cls.mapServiceNode = map[string]map[int]struct{}{}
//加载本地结点的NodeList配置 //加载本地结点的NodeList配置
@@ -263,17 +266,24 @@ func (cls *Cluster) IsConfigService(serviceName string) bool {
return ok return ok
} }
func (cls *Cluster) GetNodeIdByService(serviceName string, rpcClientList []*rpc.Client, bAll bool) (error, int) {
func (cls *Cluster) GetNodeIdByService(serviceName string, rpcClientList []*rpc.Client, filterRetire bool) (error, int) {
cls.locker.RLock() cls.locker.RLock()
defer cls.locker.RUnlock() defer cls.locker.RUnlock()
mapNodeId, ok := cls.mapServiceNode[serviceName] mapNodeId, ok := cls.mapServiceNode[serviceName]
count := 0 count := 0
if ok == true { if ok == true {
for nodeId, _ := range mapNodeId { for nodeId, _ := range mapNodeId {
pClient := GetCluster().getRpcClient(nodeId) pClient,retire := GetCluster().getRpcClient(nodeId)
if pClient == nil || (bAll == false && pClient.IsConnected() == false) { if pClient == nil || pClient.IsConnected() == false {
continue continue
} }
//如果需要筛选掉退休的对retire状态的结点略过
if filterRetire == true && retire == true {
continue
}
rpcClientList[count] = pClient rpcClientList[count] = pClient
count++ count++
if count >= cap(rpcClientList) { if count >= cap(rpcClientList) {

View File

@@ -5,6 +5,7 @@ import (
"runtime" "runtime"
"github.com/duanhf2012/origin/log" "github.com/duanhf2012/origin/log"
"sync/atomic"
) )
const defaultMaxTaskChannelNum = 1000000 const defaultMaxTaskChannelNum = 1000000
@@ -21,6 +22,7 @@ type Concurrent struct {
tasks chan task tasks chan task
cbChannel chan func(error) cbChannel chan func(error)
open int32
} }
/* /*
@@ -33,6 +35,10 @@ func (c *Concurrent) OpenConcurrentByNumCPU(cpuNumMul float32) {
} }
func (c *Concurrent) OpenConcurrent(minGoroutineNum int32, maxGoroutineNum int32, maxTaskChannelNum int) { func (c *Concurrent) OpenConcurrent(minGoroutineNum int32, maxGoroutineNum int32, maxTaskChannelNum int) {
if atomic.AddInt32(&c.open,1) > 1 {
panic("repeated calls to OpenConcurrent are not allowed!")
}
c.tasks = make(chan task, maxTaskChannelNum) c.tasks = make(chan task, maxTaskChannelNum)
c.cbChannel = make(chan func(error), maxTaskChannelNum) c.cbChannel = make(chan func(error), maxTaskChannelNum)
@@ -50,7 +56,7 @@ func (c *Concurrent) AsyncDoByQueue(queueId int64, fn func() bool, cb func(err e
} }
if fn == nil && cb == nil { if fn == nil && cb == nil {
log.SStack("fn and cb is nil") log.Stack("fn and cb is nil")
return return
} }
@@ -66,7 +72,7 @@ func (c *Concurrent) AsyncDoByQueue(queueId int64, fn func() bool, cb func(err e
select { select {
case c.tasks <- task{queueId, fn, cb}: case c.tasks <- task{queueId, fn, cb}:
default: default:
log.SError("tasks channel is full") log.Error("tasks channel is full")
if cb != nil { if cb != nil {
c.pushAsyncDoCallbackEvent(func(err error) { c.pushAsyncDoCallbackEvent(func(err error) {
cb(errors.New("tasks channel is full")) cb(errors.New("tasks channel is full"))
@@ -81,11 +87,11 @@ func (c *Concurrent) Close() {
return return
} }
log.SRelease("wait close concurrent") log.Info("wait close concurrent")
c.dispatch.close() c.dispatch.close()
log.SRelease("concurrent has successfully exited") log.Info("concurrent has successfully exited")
} }
func (c *Concurrent) GetCallBackChannel() chan func(error) { func (c *Concurrent) GetCallBackChannel() chan func(error) {

View File

@@ -187,8 +187,7 @@ func (d *dispatch) DoCallback(cb func(err error)) {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.Dump(string(buf[:l]),log.String("error",errString))
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
} }
}() }()

View File

@@ -40,7 +40,7 @@ func (w *worker) run(waitGroup *sync.WaitGroup, t task) {
case tw := <-w.workerQueue: case tw := <-w.workerQueue:
if tw.isExistTask() { if tw.isExistTask() {
//exit goroutine //exit goroutine
log.SRelease("worker goroutine exit") log.Info("worker goroutine exit")
return return
} }
w.exec(&tw) w.exec(&tw)
@@ -59,9 +59,8 @@ func (w *worker) exec(t *task) {
t.cb = func(err error) { t.cb = func(err error) {
cb(errors.New(errString)) cb(errors.New(errString))
} }
log.Dump(string(buf[:l]),log.String("error",errString))
w.endCallFun(true,t) w.endCallFun(true,t)
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
} }
}() }()

View File

@@ -11,8 +11,9 @@ type CommandFunctionCB func(args interface{}) error
var commandList []*command var commandList []*command
var programName string var programName string
const( const(
boolType valueType = iota boolType valueType = 0
stringType valueType = iota stringType valueType = 1
intType valueType = 2
) )
type command struct{ type command struct{
@@ -20,6 +21,7 @@ type command struct{
name string name string
bValue bool bValue bool
strValue string strValue string
intValue int
usage string usage string
fn CommandFunctionCB fn CommandFunctionCB
} }
@@ -29,6 +31,8 @@ func (cmd *command) execute() error{
return cmd.fn(cmd.bValue) return cmd.fn(cmd.bValue)
}else if cmd.valType == stringType { }else if cmd.valType == stringType {
return cmd.fn(cmd.strValue) return cmd.fn(cmd.strValue)
}else if cmd.valType == intType {
return cmd.fn(cmd.intValue)
}else{ }else{
return fmt.Errorf("Unknow command type.") return fmt.Errorf("Unknow command type.")
} }
@@ -72,6 +76,16 @@ func RegisterCommandBool(cmdName string, defaultValue bool, usage string,fn Comm
commandList = append(commandList,&cmd) commandList = append(commandList,&cmd)
} }
func RegisterCommandInt(cmdName string, defaultValue int, usage string,fn CommandFunctionCB){
var cmd command
cmd.valType = intType
cmd.name = cmdName
cmd.fn = fn
cmd.usage = usage
flag.IntVar(&cmd.intValue, cmdName, defaultValue, usage)
commandList = append(commandList,&cmd)
}
func RegisterCommandString(cmdName string, defaultValue string, usage string,fn CommandFunctionCB){ func RegisterCommandString(cmdName string, defaultValue string, usage string,fn CommandFunctionCB){
var cmd command var cmd command
cmd.valType = stringType cmd.valType = stringType

View File

@@ -215,7 +215,7 @@ func (processor *EventProcessor) EventHandler(ev IEvent) {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[",errString,"]\n",string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -230,13 +230,13 @@ func (processor *EventProcessor) EventHandler(ev IEvent) {
func (processor *EventProcessor) castEvent(event IEvent){ func (processor *EventProcessor) castEvent(event IEvent){
if processor.mapListenerEvent == nil { if processor.mapListenerEvent == nil {
log.SError("mapListenerEvent not init!") log.Error("mapListenerEvent not init!")
return return
} }
eventProcessor,ok := processor.mapListenerEvent[event.GetEventType()] eventProcessor,ok := processor.mapListenerEvent[event.GetEventType()]
if ok == false || processor == nil{ if ok == false || processor == nil{
log.SDebug("event type ",event.GetEventType()," not listen.") log.Debug("event is not listen",log.Int("event type",int(event.GetEventType())))
return return
} }

View File

@@ -7,16 +7,15 @@ const (
ServiceRpcRequestEvent EventType = -1 ServiceRpcRequestEvent EventType = -1
ServiceRpcResponseEvent EventType = -2 ServiceRpcResponseEvent EventType = -2
Sys_Event_Tcp EventType = -3 Sys_Event_Tcp EventType = -3
Sys_Event_Http_Event EventType = -4 Sys_Event_Http_Event EventType = -4
Sys_Event_WebSocket EventType = -5 Sys_Event_WebSocket EventType = -5
Sys_Event_Node_Event EventType = -6 Sys_Event_Node_Event EventType = -6
Sys_Event_DiscoverService EventType = -7 Sys_Event_DiscoverService EventType = -7
Sys_Event_DiscardGoroutine EventType = -8 Sys_Event_DiscardGoroutine EventType = -8
Sys_Event_QueueTaskFinish EventType = -9 Sys_Event_QueueTaskFinish EventType = -9
Sys_Event_Retire EventType = -10
Sys_Event_User_Define EventType = 1
Sys_Event_User_Define EventType = 1
) )

11
go.mod
View File

@@ -1,30 +1,37 @@
module github.com/duanhf2012/origin module github.com/duanhf2012/origin
go 1.19 go 1.21
require ( require (
github.com/go-sql-driver/mysql v1.6.0 github.com/go-sql-driver/mysql v1.6.0
github.com/gogo/protobuf v1.3.2
github.com/gomodule/redigo v1.8.8 github.com/gomodule/redigo v1.8.8
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/pierrec/lz4/v4 v4.1.18
github.com/shirou/gopsutil v3.21.11+incompatible
go.mongodb.org/mongo-driver v1.9.1 go.mongodb.org/mongo-driver v1.9.1
google.golang.org/protobuf v1.31.0
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
) )
require ( require (
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.0 // indirect github.com/go-stack/stack v1.8.0 // indirect
github.com/golang/snappy v0.0.1 // indirect github.com/golang/snappy v0.0.1 // indirect
github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/compress v1.13.6 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/scram v1.0.2 // indirect
github.com/xdg-go/stringprep v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/crypto v0.1.0 // indirect golang.org/x/crypto v0.1.0 // indirect
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.4.0 // indirect golang.org/x/text v0.4.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )

46
go.sum
View File

@@ -1,25 +1,25 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E= github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -32,10 +32,14 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -43,6 +47,10 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
@@ -51,47 +59,37 @@ github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyh
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c= go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c=
go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -2,27 +2,20 @@ package log // import "go.uber.org/zap/buffer"
import ( import (
"strconv" "strconv"
"sync"
) )
const _size = 9216 const _size = 9216
type Buffer struct { type Buffer struct {
bs []byte bs []byte
mu sync.Mutex // ensures atomic writes; protects the following fields //mu sync.Mutex // ensures atomic writes; protects the following fields
} }
func (buff *Buffer) Init(){ func (buff *Buffer) Init(){
buff.bs = make([]byte,_size) buff.bs = make([]byte,_size)
} }
func (buff *Buffer) Locker() {
buff.mu.Lock()
}
func (buff *Buffer) UnLocker() {
buff.mu.Unlock()
}
// AppendByte writes a single byte to the Buffer. // AppendByte writes a single byte to the Buffer.
func (b *Buffer) AppendByte(v byte) { func (b *Buffer) AppendByte(v byte) {

147
log/handler.go Normal file
View File

@@ -0,0 +1,147 @@
package log
import (
"context"
"io"
"log/slog"
"path/filepath"
"runtime"
"runtime/debug"
"sync"
)
type IOriginHandler interface {
slog.Handler
Lock()
UnLock()
}
type BaseHandler struct {
addSource bool
w io.Writer
locker sync.Mutex
}
type OriginTextHandler struct {
BaseHandler
*slog.TextHandler
}
type OriginJsonHandler struct {
BaseHandler
*slog.JSONHandler
}
func getStrLevel(level slog.Level) string{
switch level {
case LevelTrace:
return "Trace"
case LevelDebug:
return "Debug"
case LevelInfo:
return "Info"
case LevelWarning:
return "Warning"
case LevelError:
return "Error"
case LevelStack:
return "Stack"
case LevelDump:
return "Dump"
case LevelFatal:
return "Fatal"
}
return ""
}
func defaultReplaceAttr(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.LevelKey {
level := a.Value.Any().(slog.Level)
a.Value = slog.StringValue(getStrLevel(level))
}else if a.Key == slog.TimeKey && len(groups) == 0 {
a.Value = slog.StringValue(a.Value.Time().Format("2006/01/02 15:04:05"))
}else if a.Key == slog.SourceKey {
source := a.Value.Any().(*slog.Source)
source.File = filepath.Base(source.File)
}
return a
}
func NewOriginTextHandler(level slog.Level,w io.Writer,addSource bool,replaceAttr func([]string,slog.Attr) slog.Attr) slog.Handler{
var textHandler OriginTextHandler
textHandler.addSource = addSource
textHandler.w = w
textHandler.TextHandler = slog.NewTextHandler(w,&slog.HandlerOptions{
AddSource: addSource,
Level: level,
ReplaceAttr: replaceAttr,
})
return &textHandler
}
func (oh *OriginTextHandler) Handle(context context.Context, record slog.Record) error{
oh.Fill(context,&record)
oh.locker.Lock()
defer oh.locker.Unlock()
if record.Level == LevelStack || record.Level == LevelFatal{
err := oh.TextHandler.Handle(context, record)
oh.logStack(&record)
return err
}else if record.Level == LevelDump {
strDump := record.Message
record.Message = "dump info"
err := oh.TextHandler.Handle(context, record)
oh.w.Write([]byte(strDump))
return err
}
return oh.TextHandler.Handle(context, record)
}
func (b *BaseHandler) logStack(record *slog.Record){
b.w.Write(debug.Stack())
}
func (b *BaseHandler) Lock(){
b.locker.Lock()
}
func (b *BaseHandler) UnLock(){
b.locker.Unlock()
}
func NewOriginJsonHandler(level slog.Level,w io.Writer,addSource bool,replaceAttr func([]string,slog.Attr) slog.Attr) slog.Handler{
var jsonHandler OriginJsonHandler
jsonHandler.addSource = addSource
jsonHandler.w = w
jsonHandler.JSONHandler = slog.NewJSONHandler(w,&slog.HandlerOptions{
AddSource: addSource,
Level: level,
ReplaceAttr: replaceAttr,
})
return &jsonHandler
}
func (oh *OriginJsonHandler) Handle(context context.Context, record slog.Record) error{
oh.Fill(context,&record)
if record.Level == LevelStack || record.Level == LevelFatal || record.Level == LevelDump{
record.Add("stack",debug.Stack())
}
oh.locker.Lock()
defer oh.locker.Unlock()
return oh.JSONHandler.Handle(context, record)
}
func (b *BaseHandler) Fill(context context.Context, record *slog.Record) {
if b.addSource {
var pcs [1]uintptr
runtime.Callers(7, pcs[:])
record.PC = pcs[0]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,7 @@ func (slf *HttpServer) startListen() error {
for _, caFile := range slf.caFileList { for _, caFile := range slf.caFileList {
cer, err := tls.LoadX509KeyPair(caFile.CertFile, caFile.Keyfile) cer, err := tls.LoadX509KeyPair(caFile.CertFile, caFile.Keyfile)
if err != nil { if err != nil {
log.SFatal("Load CA [",caFile.CertFile,"]-[",caFile.Keyfile,"] file is fail:",err.Error()) log.Fatal("Load CA file is fail",log.String("error",err.Error()),log.String("certFile",caFile.CertFile),log.String("keyFile",caFile.Keyfile))
return err return err
} }
tlsCaList = append(tlsCaList, cer) tlsCaList = append(tlsCaList, cer)
@@ -74,7 +74,7 @@ func (slf *HttpServer) startListen() error {
} }
if err != nil { if err != nil {
log.SFatal("Listen for address ",slf.listenAddr," failure:",err.Error()) log.Fatal("Listen failure",log.String("error",err.Error()),log.String("addr:",slf.listenAddr))
return err return err
} }

View File

@@ -3,9 +3,9 @@ package processor
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/duanhf2012/origin/network"
"reflect"
"github.com/duanhf2012/origin/log" "github.com/duanhf2012/origin/log"
"github.com/duanhf2012/origin/util/bytespool"
"reflect"
) )
type MessageJsonInfo struct { type MessageJsonInfo struct {
@@ -24,7 +24,7 @@ type JsonProcessor struct {
unknownMessageHandler UnknownMessageJsonHandler unknownMessageHandler UnknownMessageJsonHandler
connectHandler ConnectJsonHandler connectHandler ConnectJsonHandler
disconnectHandler ConnectJsonHandler disconnectHandler ConnectJsonHandler
network.INetMempool bytespool.IBytesMempool
} }
type JsonPackInfo struct { type JsonPackInfo struct {
@@ -35,7 +35,7 @@ type JsonPackInfo struct {
func NewJsonProcessor() *JsonProcessor { func NewJsonProcessor() *JsonProcessor {
processor := &JsonProcessor{mapMsg:map[uint16]MessageJsonInfo{}} processor := &JsonProcessor{mapMsg:map[uint16]MessageJsonInfo{}}
processor.INetMempool = network.NewMemAreaPool() processor.IBytesMempool = bytespool.NewMemAreaPool()
return processor return processor
} }
@@ -58,7 +58,7 @@ func (jsonProcessor *JsonProcessor ) MsgRoute(clientId uint64,msg interface{}) e
func (jsonProcessor *JsonProcessor) Unmarshal(clientId uint64,data []byte) (interface{}, error) { func (jsonProcessor *JsonProcessor) Unmarshal(clientId uint64,data []byte) (interface{}, error) {
typeStruct := struct {Type int `json:"typ"`}{} typeStruct := struct {Type int `json:"typ"`}{}
defer jsonProcessor.ReleaseByteSlice(data) defer jsonProcessor.ReleaseBytes(data)
err := json.Unmarshal(data, &typeStruct) err := json.Unmarshal(data, &typeStruct)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -106,7 +106,7 @@ func (jsonProcessor *JsonProcessor) MakeRawMsg(msgType uint16,msg []byte) *JsonP
func (jsonProcessor *JsonProcessor) UnknownMsgRoute(clientId uint64,msg interface{}){ func (jsonProcessor *JsonProcessor) UnknownMsgRoute(clientId uint64,msg interface{}){
if jsonProcessor.unknownMessageHandler==nil { if jsonProcessor.unknownMessageHandler==nil {
log.SDebug("Unknown message received from ",clientId) log.Debug("Unknown message",log.Uint64("clientId",clientId))
return return
} }

View File

@@ -3,8 +3,8 @@ package processor
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/duanhf2012/origin/network" "github.com/duanhf2012/origin/util/bytespool"
"github.com/gogo/protobuf/proto" "google.golang.org/protobuf/proto"
"reflect" "reflect"
) )
@@ -26,7 +26,7 @@ type PBProcessor struct {
unknownMessageHandler UnknownMessageHandler unknownMessageHandler UnknownMessageHandler
connectHandler ConnectHandler connectHandler ConnectHandler
disconnectHandler ConnectHandler disconnectHandler ConnectHandler
network.INetMempool bytespool.IBytesMempool
} }
type PBPackInfo struct { type PBPackInfo struct {
@@ -37,7 +37,7 @@ type PBPackInfo struct {
func NewPBProcessor() *PBProcessor { func NewPBProcessor() *PBProcessor {
processor := &PBProcessor{mapMsg: map[uint16]MessageInfo{}} processor := &PBProcessor{mapMsg: map[uint16]MessageInfo{}}
processor.INetMempool = network.NewMemAreaPool() processor.IBytesMempool = bytespool.NewMemAreaPool()
return processor return processor
} }
@@ -67,7 +67,12 @@ func (pbProcessor *PBProcessor) MsgRoute(clientId uint64, msg interface{}) error
// must goroutine safe // must goroutine safe
func (pbProcessor *PBProcessor) Unmarshal(clientId uint64, data []byte) (interface{}, error) { func (pbProcessor *PBProcessor) Unmarshal(clientId uint64, data []byte) (interface{}, error) {
defer pbProcessor.ReleaseByteSlice(data) defer pbProcessor.ReleaseBytes(data)
return pbProcessor.UnmarshalWithOutRelease(clientId, data)
}
// unmarshal but not release data
func (pbProcessor *PBProcessor) UnmarshalWithOutRelease(clientId uint64, data []byte) (interface{}, error) {
var msgType uint16 var msgType uint16
if pbProcessor.LittleEndian == true { if pbProcessor.LittleEndian == true {
msgType = binary.LittleEndian.Uint16(data[:2]) msgType = binary.LittleEndian.Uint16(data[:2])

View File

@@ -40,29 +40,29 @@ func (client *TCPClient) init() {
if client.ConnNum <= 0 { if client.ConnNum <= 0 {
client.ConnNum = 1 client.ConnNum = 1
log.SRelease("invalid ConnNum, reset to ", client.ConnNum) log.Info("invalid ConnNum",log.Int("reset", client.ConnNum))
} }
if client.ConnectInterval <= 0 { if client.ConnectInterval <= 0 {
client.ConnectInterval = 3 * time.Second client.ConnectInterval = 3 * time.Second
log.SRelease("invalid ConnectInterval, reset to ", client.ConnectInterval) log.Info("invalid ConnectInterval",log.Duration("reset", client.ConnectInterval))
} }
if client.PendingWriteNum <= 0 { if client.PendingWriteNum <= 0 {
client.PendingWriteNum = 1000 client.PendingWriteNum = 1000
log.SRelease("invalid PendingWriteNum, reset to ", client.PendingWriteNum) log.Info("invalid PendingWriteNum",log.Int("reset",client.PendingWriteNum))
} }
if client.ReadDeadline == 0 { if client.ReadDeadline == 0 {
client.ReadDeadline = 15*time.Second client.ReadDeadline = 15*time.Second
log.SRelease("invalid ReadDeadline, reset to ", int64(client.ReadDeadline.Seconds()),"s") log.Info("invalid ReadDeadline",log.Int64("reset", int64(client.ReadDeadline.Seconds())))
} }
if client.WriteDeadline == 0 { if client.WriteDeadline == 0 {
client.WriteDeadline = 15*time.Second client.WriteDeadline = 15*time.Second
log.SRelease("invalid WriteDeadline, reset to ", int64(client.WriteDeadline.Seconds()),"s") log.Info("invalid WriteDeadline",log.Int64("reset", int64(client.WriteDeadline.Seconds())))
} }
if client.NewAgent == nil { if client.NewAgent == nil {
log.SFatal("NewAgent must not be nil") log.Fatal("NewAgent must not be nil")
} }
if client.cons != nil { if client.cons != nil {
log.SFatal("client is running") log.Fatal("client is running")
} }
if client.MinMsgLen == 0 { if client.MinMsgLen == 0 {
@@ -77,7 +77,7 @@ func (client *TCPClient) init() {
maxMsgLen := client.MsgParser.getMaxMsgLen(client.LenMsgLen) maxMsgLen := client.MsgParser.getMaxMsgLen(client.LenMsgLen)
if client.MaxMsgLen > maxMsgLen { if client.MaxMsgLen > maxMsgLen {
client.MaxMsgLen = maxMsgLen client.MaxMsgLen = maxMsgLen
log.SRelease("invalid MaxMsgLen, reset to ", maxMsgLen) log.Info("invalid MaxMsgLen",log.Uint32("reset", maxMsgLen))
} }
client.cons = make(ConnSet) client.cons = make(ConnSet)
@@ -102,7 +102,7 @@ func (client *TCPClient) dial() net.Conn {
return conn return conn
} }
log.SWarning("connect to ",client.Addr," error:", err.Error()) log.Warning("connect error ",log.String("error",err.Error()), log.String("Addr",client.Addr))
time.Sleep(client.ConnectInterval) time.Sleep(client.ConnectInterval)
continue continue
} }

View File

@@ -41,7 +41,7 @@ func newTCPConn(conn net.Conn, pendingWriteNum int, msgParser *MsgParser,writeDe
conn.SetWriteDeadline(time.Now().Add(writeDeadline)) conn.SetWriteDeadline(time.Now().Add(writeDeadline))
_, err := conn.Write(b) _, err := conn.Write(b)
tcpConn.msgParser.ReleaseByteSlice(b) tcpConn.msgParser.ReleaseBytes(b)
if err != nil { if err != nil {
break break
@@ -92,7 +92,7 @@ func (tcpConn *TCPConn) GetRemoteIp() string {
func (tcpConn *TCPConn) doWrite(b []byte) error{ func (tcpConn *TCPConn) doWrite(b []byte) error{
if len(tcpConn.writeChan) == cap(tcpConn.writeChan) { if len(tcpConn.writeChan) == cap(tcpConn.writeChan) {
tcpConn.ReleaseReadMsg(b) tcpConn.ReleaseReadMsg(b)
log.SError("close conn: channel full") log.Error("close conn: channel full")
tcpConn.doDestroy() tcpConn.doDestroy()
return errors.New("close conn: channel full") return errors.New("close conn: channel full")
} }
@@ -130,7 +130,7 @@ func (tcpConn *TCPConn) ReadMsg() ([]byte, error) {
} }
func (tcpConn *TCPConn) ReleaseReadMsg(byteBuff []byte){ func (tcpConn *TCPConn) ReleaseReadMsg(byteBuff []byte){
tcpConn.msgParser.ReleaseByteSlice(byteBuff) tcpConn.msgParser.ReleaseBytes(byteBuff)
} }
func (tcpConn *TCPConn) WriteMsg(args ...[]byte) error { func (tcpConn *TCPConn) WriteMsg(args ...[]byte) error {

View File

@@ -3,6 +3,7 @@ package network
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"github.com/duanhf2012/origin/util/bytespool"
"io" "io"
"math" "math"
) )
@@ -16,7 +17,7 @@ type MsgParser struct {
MaxMsgLen uint32 MaxMsgLen uint32
LittleEndian bool LittleEndian bool
INetMempool bytespool.IBytesMempool
} }
@@ -34,7 +35,7 @@ func (p *MsgParser) getMaxMsgLen(lenMsgLen int) uint32 {
} }
func (p *MsgParser) init(){ func (p *MsgParser) init(){
p.INetMempool = NewMemAreaPool() p.IBytesMempool = bytespool.NewMemAreaPool()
} }
// goroutine safe // goroutine safe
@@ -74,9 +75,9 @@ func (p *MsgParser) Read(conn *TCPConn) ([]byte, error) {
} }
// data // data
msgData := p.MakeByteSlice(int(msgLen)) msgData := p.MakeBytes(int(msgLen))
if _, err := io.ReadFull(conn, msgData[:msgLen]); err != nil { if _, err := io.ReadFull(conn, msgData[:msgLen]); err != nil {
p.ReleaseByteSlice(msgData) p.ReleaseBytes(msgData)
return nil, err return nil, err
} }
@@ -99,7 +100,7 @@ func (p *MsgParser) Write(conn *TCPConn, args ...[]byte) error {
} }
//msg := make([]byte, uint32(p.lenMsgLen)+msgLen) //msg := make([]byte, uint32(p.lenMsgLen)+msgLen)
msg := p.MakeByteSlice(p.LenMsgLen+int(msgLen)) msg := p.MakeBytes(p.LenMsgLen+int(msgLen))
// write len // write len
switch p.LenMsgLen { switch p.LenMsgLen {
case 1: case 1:

View File

@@ -2,6 +2,7 @@ package network
import ( import (
"github.com/duanhf2012/origin/log" "github.com/duanhf2012/origin/log"
"github.com/duanhf2012/origin/util/bytespool"
"net" "net"
"sync" "sync"
"time" "time"
@@ -43,52 +44,52 @@ func (server *TCPServer) Start() {
func (server *TCPServer) init() { func (server *TCPServer) init() {
ln, err := net.Listen("tcp", server.Addr) ln, err := net.Listen("tcp", server.Addr)
if err != nil { if err != nil {
log.SFatal("Listen tcp error:", err.Error()) log.Fatal("Listen tcp fail",log.String("error", err.Error()))
} }
if server.MaxConnNum <= 0 { if server.MaxConnNum <= 0 {
server.MaxConnNum = Default_MaxConnNum server.MaxConnNum = Default_MaxConnNum
log.SRelease("invalid MaxConnNum, reset to ", server.MaxConnNum) log.Info("invalid MaxConnNum",log.Int("reset", server.MaxConnNum))
} }
if server.PendingWriteNum <= 0 { if server.PendingWriteNum <= 0 {
server.PendingWriteNum = Default_PendingWriteNum server.PendingWriteNum = Default_PendingWriteNum
log.SRelease("invalid PendingWriteNum, reset to ", server.PendingWriteNum) log.Info("invalid PendingWriteNum",log.Int("reset", server.PendingWriteNum))
} }
if server.LenMsgLen <= 0 { if server.LenMsgLen <= 0 {
server.LenMsgLen = Default_LenMsgLen server.LenMsgLen = Default_LenMsgLen
log.SRelease("invalid LenMsgLen, reset to ", server.LenMsgLen) log.Info("invalid LenMsgLen", log.Int("reset", server.LenMsgLen))
} }
if server.MaxMsgLen <= 0 { if server.MaxMsgLen <= 0 {
server.MaxMsgLen = Default_MaxMsgLen server.MaxMsgLen = Default_MaxMsgLen
log.SRelease("invalid MaxMsgLen, reset to ", server.MaxMsgLen) log.Info("invalid MaxMsgLen", log.Uint32("reset to", server.MaxMsgLen))
} }
maxMsgLen := server.MsgParser.getMaxMsgLen(server.LenMsgLen) maxMsgLen := server.MsgParser.getMaxMsgLen(server.LenMsgLen)
if server.MaxMsgLen > maxMsgLen { if server.MaxMsgLen > maxMsgLen {
server.MaxMsgLen = maxMsgLen server.MaxMsgLen = maxMsgLen
log.SRelease("invalid MaxMsgLen, reset to ", maxMsgLen) log.Info("invalid MaxMsgLen",log.Uint32("reset", maxMsgLen))
} }
if server.MinMsgLen <= 0 { if server.MinMsgLen <= 0 {
server.MinMsgLen = Default_MinMsgLen server.MinMsgLen = Default_MinMsgLen
log.SRelease("invalid MinMsgLen, reset to ", server.MinMsgLen) log.Info("invalid MinMsgLen",log.Uint32("reset", server.MinMsgLen))
} }
if server.WriteDeadline == 0 { if server.WriteDeadline == 0 {
server.WriteDeadline = Default_WriteDeadline server.WriteDeadline = Default_WriteDeadline
log.SRelease("invalid WriteDeadline, reset to ", server.WriteDeadline.Seconds(),"s") log.Info("invalid WriteDeadline",log.Int64("reset",int64(server.WriteDeadline.Seconds())))
} }
if server.ReadDeadline == 0 { if server.ReadDeadline == 0 {
server.ReadDeadline = Default_ReadDeadline server.ReadDeadline = Default_ReadDeadline
log.SRelease("invalid ReadDeadline, reset to ", server.ReadDeadline.Seconds(),"s") log.Info("invalid ReadDeadline",log.Int64("reset", int64(server.ReadDeadline.Seconds())))
} }
if server.NewAgent == nil { if server.NewAgent == nil {
log.SFatal("NewAgent must not be nil") log.Fatal("NewAgent must not be nil")
} }
server.ln = ln server.ln = ln
@@ -96,12 +97,12 @@ func (server *TCPServer) init() {
server.MsgParser.init() server.MsgParser.init()
} }
func (server *TCPServer) SetNetMempool(mempool INetMempool){ func (server *TCPServer) SetNetMempool(mempool bytespool.IBytesMempool){
server.INetMempool = mempool server.IBytesMempool = mempool
} }
func (server *TCPServer) GetNetMempool() INetMempool{ func (server *TCPServer) GetNetMempool() bytespool.IBytesMempool {
return server.INetMempool return server.IBytesMempool
} }
func (server *TCPServer) run() { func (server *TCPServer) run() {
@@ -121,7 +122,7 @@ func (server *TCPServer) run() {
if max := 1 * time.Second; tempDelay > max { if max := 1 * time.Second; tempDelay > max {
tempDelay = max tempDelay = max
} }
log.SRelease("accept error:",err.Error(),"; retrying in ", tempDelay) log.Info("accept fail",log.String("error",err.Error()),log.Duration("sleep time", tempDelay))
time.Sleep(tempDelay) time.Sleep(tempDelay)
continue continue
} }
@@ -135,7 +136,7 @@ func (server *TCPServer) run() {
if len(server.conns) >= server.MaxConnNum { if len(server.conns) >= server.MaxConnNum {
server.mutexConns.Unlock() server.mutexConns.Unlock()
conn.Close() conn.Close()
log.SWarning("too many connections") log.Warning("too many connections")
continue continue
} }

View File

@@ -40,29 +40,29 @@ func (client *WSClient) init() {
if client.ConnNum <= 0 { if client.ConnNum <= 0 {
client.ConnNum = 1 client.ConnNum = 1
log.SRelease("invalid ConnNum, reset to ", client.ConnNum) log.Info("invalid ConnNum",log.Int("reset", client.ConnNum))
} }
if client.ConnectInterval <= 0 { if client.ConnectInterval <= 0 {
client.ConnectInterval = 3 * time.Second client.ConnectInterval = 3 * time.Second
log.SRelease("invalid ConnectInterval, reset to ", client.ConnectInterval) log.Info("invalid ConnectInterval",log.Duration("reset", client.ConnectInterval))
} }
if client.PendingWriteNum <= 0 { if client.PendingWriteNum <= 0 {
client.PendingWriteNum = 100 client.PendingWriteNum = 100
log.SRelease("invalid PendingWriteNum, reset to ", client.PendingWriteNum) log.Info("invalid PendingWriteNum",log.Int("reset", client.PendingWriteNum))
} }
if client.MaxMsgLen <= 0 { if client.MaxMsgLen <= 0 {
client.MaxMsgLen = 4096 client.MaxMsgLen = 4096
log.SRelease("invalid MaxMsgLen, reset to ", client.MaxMsgLen) log.Info("invalid MaxMsgLen",log.Uint32("reset", client.MaxMsgLen))
} }
if client.HandshakeTimeout <= 0 { if client.HandshakeTimeout <= 0 {
client.HandshakeTimeout = 10 * time.Second client.HandshakeTimeout = 10 * time.Second
log.SRelease("invalid HandshakeTimeout, reset to ", client.HandshakeTimeout) log.Info("invalid HandshakeTimeout",log.Duration("reset", client.HandshakeTimeout))
} }
if client.NewAgent == nil { if client.NewAgent == nil {
log.SFatal("NewAgent must not be nil") log.Fatal("NewAgent must not be nil")
} }
if client.cons != nil { if client.cons != nil {
log.SFatal("client is running") log.Fatal("client is running")
} }
if client.MessageType == 0 { if client.MessageType == 0 {
@@ -83,7 +83,7 @@ func (client *WSClient) dial() *websocket.Conn {
return conn return conn
} }
log.SRelease("connect to ", client.Addr," error: ", err.Error()) log.Info("connect fail", log.String("error",err.Error()),log.String("addr",client.Addr))
time.Sleep(client.ConnectInterval) time.Sleep(client.ConnectInterval)
continue continue
} }

View File

@@ -75,7 +75,7 @@ func (wsConn *WSConn) Close() {
func (wsConn *WSConn) doWrite(b []byte) { func (wsConn *WSConn) doWrite(b []byte) {
if len(wsConn.writeChan) == cap(wsConn.writeChan) { if len(wsConn.writeChan) == cap(wsConn.writeChan) {
log.SDebug("close conn: channel full") log.Debug("close conn: channel full")
wsConn.doDestroy() wsConn.doDestroy()
return return
} }

View File

@@ -47,7 +47,7 @@ func (handler *WSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
conn, err := handler.upgrader.Upgrade(w, r, nil) conn, err := handler.upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
log.SError("upgrade error: ", err.Error()) log.Error("upgrade fail",log.String("error",err.Error()))
return return
} }
conn.SetReadLimit(int64(handler.maxMsgLen)) conn.SetReadLimit(int64(handler.maxMsgLen))
@@ -67,7 +67,7 @@ func (handler *WSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(handler.conns) >= handler.maxConnNum { if len(handler.conns) >= handler.maxConnNum {
handler.mutexConns.Unlock() handler.mutexConns.Unlock()
conn.Close() conn.Close()
log.SWarning("too many connections") log.Warning("too many connections")
return return
} }
handler.conns[conn] = struct{}{} handler.conns[conn] = struct{}{}
@@ -95,27 +95,27 @@ func (server *WSServer) SetMessageType(messageType int) {
func (server *WSServer) Start() { func (server *WSServer) Start() {
ln, err := net.Listen("tcp", server.Addr) ln, err := net.Listen("tcp", server.Addr)
if err != nil { if err != nil {
log.SFatal("WSServer Listen fail:", err.Error()) log.Fatal("WSServer Listen fail",log.String("error", err.Error()))
} }
if server.MaxConnNum <= 0 { if server.MaxConnNum <= 0 {
server.MaxConnNum = 100 server.MaxConnNum = 100
log.SRelease("invalid MaxConnNum, reset to ", server.MaxConnNum) log.Info("invalid MaxConnNum", log.Int("reset", server.MaxConnNum))
} }
if server.PendingWriteNum <= 0 { if server.PendingWriteNum <= 0 {
server.PendingWriteNum = 100 server.PendingWriteNum = 100
log.SRelease("invalid PendingWriteNum, reset to ", server.PendingWriteNum) log.Info("invalid PendingWriteNum", log.Int("reset", server.PendingWriteNum))
} }
if server.MaxMsgLen <= 0 { if server.MaxMsgLen <= 0 {
server.MaxMsgLen = 4096 server.MaxMsgLen = 4096
log.SRelease("invalid MaxMsgLen, reset to ", server.MaxMsgLen) log.Info("invalid MaxMsgLen", log.Uint32("reset", server.MaxMsgLen))
} }
if server.HTTPTimeout <= 0 { if server.HTTPTimeout <= 0 {
server.HTTPTimeout = 10 * time.Second server.HTTPTimeout = 10 * time.Second
log.SRelease("invalid HTTPTimeout, reset to ", server.HTTPTimeout) log.Info("invalid HTTPTimeout", log.Duration("reset", server.HTTPTimeout))
} }
if server.NewAgent == nil { if server.NewAgent == nil {
log.SFatal("NewAgent must not be nil") log.Fatal("NewAgent must not be nil")
} }
if server.CertFile != "" || server.KeyFile != "" { if server.CertFile != "" || server.KeyFile != "" {
@@ -126,7 +126,7 @@ func (server *WSServer) Start() {
config.Certificates = make([]tls.Certificate, 1) config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(server.CertFile, server.KeyFile) config.Certificates[0], err = tls.LoadX509KeyPair(server.CertFile, server.KeyFile)
if err != nil { if err != nil {
log.SFatal("LoadX509KeyPair fail:", err.Error()) log.Fatal("LoadX509KeyPair fail",log.String("error", err.Error()))
} }
ln = tls.NewListener(ln, config) ln = tls.NewListener(ln, config)

View File

@@ -11,7 +11,6 @@ import (
"github.com/duanhf2012/origin/util/buildtime" "github.com/duanhf2012/origin/util/buildtime"
"github.com/duanhf2012/origin/util/timer" "github.com/duanhf2012/origin/util/timer"
"io" "io"
slog "log"
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
@@ -20,6 +19,7 @@ import (
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/duanhf2012/origin/util/sysprocess"
) )
var sig chan os.Signal var sig chan os.Signal
@@ -28,8 +28,12 @@ var preSetupService []service.IService //预安装
var profilerInterval time.Duration var profilerInterval time.Duration
var bValid bool var bValid bool
var configDir = "./config/" var configDir = "./config/"
var logLevel string = "debug"
var logPath string const(
SingleStop syscall.Signal = 10
SignalRetire syscall.Signal = 12
)
type BuildOSType = int8 type BuildOSType = int8
const( const(
@@ -39,20 +43,28 @@ const(
) )
func init() { func init() {
sig = make(chan os.Signal, 3) sig = make(chan os.Signal, 4)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.Signal(10)) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, SingleStop,SignalRetire)
console.RegisterCommandBool("help", false, "<-help> This help.", usage) console.RegisterCommandBool("help", false, "<-help> This help.", usage)
console.RegisterCommandString("name", "", "<-name nodeName> Node's name.", setName) console.RegisterCommandString("name", "", "<-name nodeName> Node's name.", setName)
console.RegisterCommandString("start", "", "<-start nodeid=nodeid> Run originserver.", startNode) console.RegisterCommandString("start", "", "<-start nodeid=nodeid> Run originserver.", startNode)
console.RegisterCommandString("stop", "", "<-stop nodeid=nodeid> Stop originserver process.", stopNode) console.RegisterCommandString("stop", "", "<-stop nodeid=nodeid> Stop originserver process.", stopNode)
console.RegisterCommandString("retire", "", "<-retire nodeid=nodeid> retire originserver process.", retireNode)
console.RegisterCommandString("config", "", "<-config path> Configuration file path.", setConfigPath) console.RegisterCommandString("config", "", "<-config path> Configuration file path.", setConfigPath)
console.RegisterCommandString("console", "", "<-console true|false> Turn on or off screen log output.", openConsole) console.RegisterCommandString("console", "", "<-console true|false> Turn on or off screen log output.", openConsole)
console.RegisterCommandString("loglevel", "debug", "<-loglevel debug|release|warning|error|fatal> Set loglevel.", setLevel) console.RegisterCommandString("loglevel", "debug", "<-loglevel debug|release|warning|error|fatal> Set loglevel.", setLevel)
console.RegisterCommandString("logpath", "", "<-logpath path> Set log file path.", setLogPath) console.RegisterCommandString("logpath", "", "<-logpath path> Set log file path.", setLogPath)
console.RegisterCommandInt("logsize", 0, "<-logsize size> Set log size(MB).", setLogSize)
console.RegisterCommandInt("logchannelcap", 0, "<-logchannelcap num> Set log channel cap.", setLogChannelCapNum)
console.RegisterCommandString("pprof", "", "<-pprof ip:port> Open performance analysis.", setPprof) console.RegisterCommandString("pprof", "", "<-pprof ip:port> Open performance analysis.", setPprof)
} }
func notifyAllServiceRetire(){
service.NotifyAllServiceRetire()
}
func usage(val interface{}) error { func usage(val interface{}) error {
ret := val.(bool) ret := val.(bool)
if ret == false { if ret == false {
@@ -144,7 +156,7 @@ func initNode(id int) {
nodeId = id nodeId = id
err := cluster.GetCluster().Init(GetNodeId(), Setup) err := cluster.GetCluster().Init(GetNodeId(), Setup)
if err != nil { if err != nil {
log.SFatal("read system config is error ", err.Error()) log.Fatal("read system config is error ",log.ErrorAttr("error",err))
} }
err = initLog() err = initLog()
@@ -168,7 +180,7 @@ func initNode(id int) {
} }
if bSetup == false { if bSetup == false {
log.SFatal("Service name "+serviceName+" configuration error") log.Fatal("Service name "+serviceName+" configuration error")
} }
} }
@@ -177,13 +189,13 @@ func initNode(id int) {
} }
func initLog() error { func initLog() error {
if logPath == "" { if log.LogPath == "" {
setLogPath("./log") setLogPath("./log")
} }
localnodeinfo := cluster.GetCluster().GetLocalNodeInfo() localnodeinfo := cluster.GetCluster().GetLocalNodeInfo()
filepre := fmt.Sprintf("%s_%d_", localnodeinfo.NodeName, localnodeinfo.NodeId) filepre := fmt.Sprintf("%s_%d_", localnodeinfo.NodeName, localnodeinfo.NodeId)
logger, err := log.New(logLevel, logPath, filepre, slog.LstdFlags|slog.Lshortfile, 10) logger, err := log.NewTextLogger(log.LogLevel,log.LogPath,filepre,true,log.LogChannelCap)
if err != nil { if err != nil {
fmt.Printf("cannot create log file!\n") fmt.Printf("cannot create log file!\n")
return err return err
@@ -200,6 +212,37 @@ func Start() {
} }
} }
func retireNode(args interface{}) error {
//1.解析参数
param := args.(string)
if param == "" {
return nil
}
sParam := strings.Split(param, "=")
if len(sParam) != 2 {
return fmt.Errorf("invalid option %s", param)
}
if sParam[0] != "nodeid" {
return fmt.Errorf("invalid option %s", param)
}
nId, err := strconv.Atoi(sParam[1])
if err != nil {
return fmt.Errorf("invalid option %s", param)
}
processId, err := getRunProcessPid(nId)
if err != nil {
return err
}
RetireProcess(processId)
return nil
}
func stopNode(args interface{}) error { func stopNode(args interface{}) error {
//1.解析参数 //1.解析参数
param := args.(string) param := args.(string)
@@ -214,12 +257,12 @@ func stopNode(args interface{}) error {
if sParam[0] != "nodeid" { if sParam[0] != "nodeid" {
return fmt.Errorf("invalid option %s", param) return fmt.Errorf("invalid option %s", param)
} }
nodeId, err := strconv.Atoi(sParam[1]) nId, err := strconv.Atoi(sParam[1])
if err != nil { if err != nil {
return fmt.Errorf("invalid option %s", param) return fmt.Errorf("invalid option %s", param)
} }
processId, err := getRunProcessPid(nodeId) processId, err := getRunProcessPid(nId)
if err != nil { if err != nil {
return err return err
} }
@@ -246,20 +289,43 @@ func startNode(args interface{}) error {
if err != nil { if err != nil {
return fmt.Errorf("invalid option %s", param) return fmt.Errorf("invalid option %s", param)
} }
for{
processId, pErr := getRunProcessPid(nodeId)
if pErr != nil {
break
}
name, cErr := sysprocess.GetProcessNameByPID(int32(processId))
myName, mErr := sysprocess.GetMyProcessName()
//当前进程名获取失败,不应该发生
if mErr != nil {
log.SInfo("get my process's name is error,", err.Error())
os.Exit(-1)
}
//进程id存在而且进程名也相同被认为是当前进程重复运行
if cErr == nil && name == myName {
log.SInfo(fmt.Sprintf("repeat runs are not allowed,node is %d,processid is %d",nodeId,processId))
os.Exit(-1)
}
break
}
//2.记录进程id号
log.Info("Start running server.")
writeProcessPid(nodeId)
timer.StartTimer(10*time.Millisecond, 1000000) timer.StartTimer(10*time.Millisecond, 1000000)
log.SRelease("Start running server.")
//2.初始化node //3.初始化node
initNode(nodeId) initNode(nodeId)
//3.运行service //4.运行service
service.Start() service.Start()
//4.运行集群 //5.运行集群
cluster.GetCluster().Start() cluster.GetCluster().Start()
//5.记录进程id号
writeProcessPid(nodeId)
//6.监听程序退出信号&性能报告 //6.监听程序退出信号&性能报告
bRun := true bRun := true
@@ -267,20 +333,29 @@ func startNode(args interface{}) error {
if profilerInterval > 0 { if profilerInterval > 0 {
pProfilerTicker = time.NewTicker(profilerInterval) pProfilerTicker = time.NewTicker(profilerInterval)
} }
for bRun { for bRun {
select { select {
case <-sig: case s := <-sig:
log.SRelease("receipt stop signal.") signal := s.(syscall.Signal)
bRun = false if signal == SignalRetire {
log.Info("receipt retire signal.")
notifyAllServiceRetire()
}else {
bRun = false
log.Info("receipt stop signal.")
}
case <-pProfilerTicker.C: case <-pProfilerTicker.C:
profiler.Report() profiler.Report()
} }
} }
cluster.GetCluster().Stop() cluster.GetCluster().Stop()
//7.退出 //7.退出
service.StopAllService() service.StopAllService()
log.SRelease("Server is stop.") log.Info("Server is stop.")
log.Close()
return nil return nil
} }
@@ -304,11 +379,6 @@ func GetConfigDir() string {
return configDir return configDir
} }
func SetSysLog(strLevel string, pathname string, flag int) {
logs, _ := log.New(strLevel, pathname, "", flag, 10)
log.Export(logs)
}
func OpenProfilerReport(interval time.Duration) { func OpenProfilerReport(interval time.Duration) {
profilerInterval = interval profilerInterval = interval
} }
@@ -333,9 +403,24 @@ func setLevel(args interface{}) error {
return nil return nil
} }
logLevel = strings.TrimSpace(args.(string)) strlogLevel := strings.TrimSpace(args.(string))
if logLevel != "debug" && logLevel != "release" && logLevel != "warning" && logLevel != "error" && logLevel != "fatal" { switch strlogLevel {
return errors.New("unknown level: " + logLevel) case "trace":
log.LogLevel = log.LevelTrace
case "debug":
log.LogLevel = log.LevelDebug
case "info":
log.LogLevel = log.LevelInfo
case "warning":
log.LogLevel = log.LevelWarning
case "error":
log.LogLevel = log.LevelError
case "stack":
log.LogLevel = log.LevelStack
case "fatal":
log.LogLevel = log.LevelFatal
default:
return errors.New("unknown level: " + strlogLevel)
} }
return nil return nil
} }
@@ -344,18 +429,48 @@ func setLogPath(args interface{}) error {
if args == "" { if args == "" {
return nil return nil
} }
logPath = strings.TrimSpace(args.(string))
dir, err := os.Stat(logPath) //这个文件夹不存在 log.LogPath = strings.TrimSpace(args.(string))
dir, err := os.Stat(log.LogPath) //这个文件夹不存在
if err == nil && dir.IsDir() == false { if err == nil && dir.IsDir() == false {
return errors.New("Not found dir " + logPath) return errors.New("Not found dir " + log.LogPath)
} }
if err != nil { if err != nil {
err = os.Mkdir(logPath, os.ModePerm) err = os.Mkdir(log.LogPath, os.ModePerm)
if err != nil { if err != nil {
return errors.New("Cannot create dir " + logPath) return errors.New("Cannot create dir " + log.LogPath)
} }
} }
return nil return nil
} }
func setLogSize(args interface{}) error {
if args == "" {
return nil
}
logSize,ok := args.(int)
if ok == false{
return errors.New("param logsize is error")
}
log.LogSize = int64(logSize)*1024*1024
return nil
}
func setLogChannelCapNum(args interface{}) error {
if args == "" {
return nil
}
logChannelCap,ok := args.(int)
if ok == false{
return errors.New("param logsize is error")
}
log.LogChannelCap = logChannelCap
return nil
}

View File

@@ -8,7 +8,7 @@ import (
) )
func KillProcess(processId int){ func KillProcess(processId int){
err := syscall.Kill(processId,syscall.Signal(10)) err := syscall.Kill(processId,SingleStop)
if err != nil { if err != nil {
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err) fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
}else{ }else{
@@ -19,3 +19,12 @@ func KillProcess(processId int){
func GetBuildOSType() BuildOSType{ func GetBuildOSType() BuildOSType{
return Linux return Linux
} }
func RetireProcess(processId int){
err := syscall.Kill(processId,SignalRetire)
if err != nil {
fmt.Printf("retire processid %d is fail:%+v.\n",processId,err)
}else{
fmt.Printf("retire processid %d is successful.\n",processId)
}
}

View File

@@ -8,7 +8,7 @@ import (
) )
func KillProcess(processId int){ func KillProcess(processId int){
err := syscall.Kill(processId,syscall.Signal(10)) err := syscall.Kill(processId,SingleStop)
if err != nil { if err != nil {
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err) fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
}else{ }else{
@@ -19,3 +19,12 @@ func KillProcess(processId int){
func GetBuildOSType() BuildOSType{ func GetBuildOSType() BuildOSType{
return Mac return Mac
} }
func RetireProcess(processId int){
err := syscall.Kill(processId,SignalRetire)
if err != nil {
fmt.Printf("retire processid %d is fail:%+v.\n",processId,err)
}else{
fmt.Printf("retire processid %d is successful.\n",processId)
}
}

View File

@@ -2,10 +2,28 @@
package node package node
func KillProcess(processId int){ import (
"os"
"fmt"
)
func KillProcess(processId int){
procss,err := os.FindProcess(processId)
if err != nil {
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
return
}
err = procss.Kill()
if err != nil {
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
}
} }
func GetBuildOSType() BuildOSType{ func GetBuildOSType() BuildOSType{
return Windows return Windows
} }
func RetireProcess(processId int){
fmt.Printf("This command does not support Windows")
}

View File

@@ -167,7 +167,7 @@ func DefaultReportFunction(name string,callNum int,costTime time.Duration,record
elem = elem.Next() elem = elem.Next()
} }
log.SRelease(strReport) log.SInfo("report",strReport)
} }
func Report() { func Report() {

View File

@@ -1,7 +1,6 @@
package rpc package rpc
import ( import (
"container/list"
"errors" "errors"
"github.com/duanhf2012/origin/network" "github.com/duanhf2012/origin/network"
"reflect" "reflect"
@@ -9,6 +8,7 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/duanhf2012/origin/log"
) )
const( const(
@@ -20,7 +20,7 @@ const(
DefaultConnectInterval = 2*time.Second DefaultConnectInterval = 2*time.Second
DefaultCheckRpcCallTimeoutInterval = 5*time.Second DefaultCheckRpcCallTimeoutInterval = 1*time.Second
DefaultRpcTimeout = 15*time.Second DefaultRpcTimeout = 15*time.Second
) )
@@ -30,9 +30,9 @@ type IRealClient interface {
SetConn(conn *network.TCPConn) SetConn(conn *network.TCPConn)
Close(waitDone bool) Close(waitDone bool)
AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{}) error AsyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{},cancelable bool) (CancelRpc,error)
Go(rpcHandler IRpcHandler, noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call Go(timeout time.Duration,rpcHandler IRpcHandler, noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call
RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call RawGo(timeout time.Duration,rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call
IsConnected() bool IsConnected() bool
Run() Run()
@@ -44,11 +44,11 @@ type Client struct {
nodeId int nodeId int
pendingLock sync.RWMutex pendingLock sync.RWMutex
startSeq uint64 startSeq uint64
pending map[uint64]*list.Element pending map[uint64]*Call
pendingTimer *list.List
callRpcTimeout time.Duration callRpcTimeout time.Duration
maxCheckCallRpcCount int maxCheckCallRpcCount int
callTimerHeap CallTimerHeap
IRealClient IRealClient
} }
@@ -59,7 +59,6 @@ func (client *Client) NewClientAgent(conn *network.TCPConn) network.Agent {
} }
func (bc *Client) makeCallFail(call *Call) { func (bc *Client) makeCallFail(call *Call) {
bc.removePending(call.Seq)
if call.callback != nil && call.callback.IsValid() { if call.callback != nil && call.callback.IsValid() {
call.rpcHandler.PushRpcResponse(call) call.rpcHandler.PushRpcResponse(call)
} else { } else {
@@ -70,54 +69,52 @@ func (bc *Client) makeCallFail(call *Call) {
func (bc *Client) checkRpcCallTimeout() { func (bc *Client) checkRpcCallTimeout() {
for{ for{
time.Sleep(DefaultCheckRpcCallTimeoutInterval) time.Sleep(DefaultCheckRpcCallTimeoutInterval)
now := time.Now()
for i := 0; i < bc.maxCheckCallRpcCount; i++ { for i := 0; i < bc.maxCheckCallRpcCount; i++ {
bc.pendingLock.Lock() bc.pendingLock.Lock()
if bc.pendingTimer == nil {
callSeq := bc.callTimerHeap.PopTimeout()
if callSeq == 0 {
bc.pendingLock.Unlock() bc.pendingLock.Unlock()
break break
} }
pElem := bc.pendingTimer.Front() pCall := bc.pending[callSeq]
if pElem == nil { if pCall == nil {
bc.pendingLock.Unlock()
break
}
pCall := pElem.Value.(*Call)
if now.Sub(pCall.callTime) > bc.callRpcTimeout {
strTimeout := strconv.FormatInt(int64(bc.callRpcTimeout/time.Second), 10)
pCall.Err = errors.New("RPC call takes more than " + strTimeout + " seconds")
bc.makeCallFail(pCall)
bc.pendingLock.Unlock() bc.pendingLock.Unlock()
log.Error("call seq is not find",log.Uint64("seq", callSeq))
continue continue
} }
delete(bc.pending,callSeq)
strTimeout := strconv.FormatInt(int64(pCall.TimeOut.Seconds()), 10)
pCall.Err = errors.New("RPC call takes more than " + strTimeout + " seconds,method is "+pCall.ServiceMethod)
log.Error("call timeout",log.String("error",pCall.Err.Error()))
bc.makeCallFail(pCall)
bc.pendingLock.Unlock() bc.pendingLock.Unlock()
break continue
} }
} }
} }
func (client *Client) InitPending() { func (client *Client) InitPending() {
client.pendingLock.Lock() client.pendingLock.Lock()
if client.pending != nil { client.callTimerHeap.Init()
for _, v := range client.pending { client.pending = make(map[uint64]*Call,4096)
v.Value.(*Call).Err = errors.New("node is disconnect")
v.Value.(*Call).done <- v.Value.(*Call)
}
}
client.pending = make(map[uint64]*list.Element, 4096)
client.pendingTimer = list.New()
client.pendingLock.Unlock() client.pendingLock.Unlock()
} }
func (bc *Client) AddPending(call *Call) { func (bc *Client) AddPending(call *Call) {
bc.pendingLock.Lock() bc.pendingLock.Lock()
call.callTime = time.Now()
elemTimer := bc.pendingTimer.PushBack(call) if call.Seq == 0 {
bc.pending[call.Seq] = elemTimer //如果下面发送失败,将会一一直存在这里 bc.pendingLock.Unlock()
log.Stack("call is error.")
return
}
bc.pending[call.Seq] = call
bc.callTimerHeap.AddTimer(call.Seq,call.TimeOut)
bc.pendingLock.Unlock() bc.pendingLock.Unlock()
} }
@@ -136,30 +133,45 @@ func (bc *Client) removePending(seq uint64) *Call {
if ok == false { if ok == false {
return nil return nil
} }
call := v.Value.(*Call)
bc.pendingTimer.Remove(v) bc.callTimerHeap.Cancel(seq)
delete(bc.pending, seq) delete(bc.pending, seq)
return call return v
} }
func (bc *Client) FindPending(seq uint64) *Call { func (bc *Client) FindPending(seq uint64) (pCall *Call) {
if seq == 0 { if seq == 0 {
return nil return nil
} }
bc.pendingLock.Lock() bc.pendingLock.Lock()
v, ok := bc.pending[seq] pCall = bc.pending[seq]
if ok == false {
bc.pendingLock.Unlock()
return nil
}
pCall := v.Value.(*Call)
bc.pendingLock.Unlock() bc.pendingLock.Unlock()
return pCall return pCall
} }
func (bc *Client) cleanPending(){
bc.pendingLock.Lock()
for {
callSeq := bc.callTimerHeap.PopFirst()
if callSeq == 0 {
break
}
pCall := bc.pending[callSeq]
if pCall == nil {
log.Error("call Seq is not find",log.Uint64("seq",callSeq))
continue
}
delete(bc.pending,callSeq)
pCall.Err = errors.New("nodeid is disconnect ")
bc.makeCallFail(pCall)
}
bc.pendingLock.Unlock()
}
func (bc *Client) generateSeq() uint64 { func (bc *Client) generateSeq() uint64 {
return atomic.AddUint64(&bc.startSeq, 1) return atomic.AddUint64(&bc.startSeq, 1)
} }

102
rpc/compressor.go Normal file
View File

@@ -0,0 +1,102 @@
package rpc
import (
"errors"
"fmt"
"github.com/duanhf2012/origin/util/bytespool"
"github.com/pierrec/lz4/v4"
"runtime"
)
var memPool bytespool.IBytesMempool = bytespool.NewMemAreaPool()
type ICompressor interface {
CompressBlock(src []byte) ([]byte, error) //dst如果有预申请使用dst内存传入nil时内部申请
UncompressBlock(src []byte) ([]byte, error) //dst如果有预申请使用dst内存传入nil时内部申请
CompressBufferCollection(buffer []byte) //压缩的Buffer内存回收
UnCompressBufferCollection(buffer []byte) //解压缩的Buffer内存回收
}
var compressor ICompressor
func init(){
SetCompressor(&Lz4Compressor{})
}
func SetCompressor(cp ICompressor){
compressor = cp
}
type Lz4Compressor struct {
}
func (lc *Lz4Compressor) CompressBlock(src []byte) (dest []byte, err error) {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 4096)
l := runtime.Stack(buf, false)
errString := fmt.Sprint(r)
err = errors.New("core dump info[" + errString + "]\n" + string(buf[:l]))
}
}()
var c lz4.Compressor
var cnt int
dest = memPool.MakeBytes(lz4.CompressBlockBound(len(src))+1)
cnt, err = c.CompressBlock(src, dest[1:])
if err != nil {
memPool.ReleaseBytes(dest)
return nil,err
}
ratio := len(src) / cnt
if len(src) % cnt > 0 {
ratio += 1
}
if ratio > 255 {
memPool.ReleaseBytes(dest)
return nil,fmt.Errorf("Impermissible errors")
}
dest[0] = uint8(ratio)
dest = dest[:cnt+1]
return
}
func (lc *Lz4Compressor) UncompressBlock(src []byte) (dest []byte, err error) {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 4096)
l := runtime.Stack(buf, false)
errString := fmt.Sprint(r)
err = errors.New("core dump info[" + errString + "]\n" + string(buf[:l]))
}
}()
radio := uint8(src[0])
if radio == 0 {
return nil,fmt.Errorf("Impermissible errors")
}
dest = memPool.MakeBytes(len(src)*int(radio))
cnt, err := lz4.UncompressBlock(src[1:], dest)
if err != nil {
memPool.ReleaseBytes(dest)
return nil,err
}
return dest[:cnt],nil
}
func (lc *Lz4Compressor) compressBlockBound(n int) int{
return lz4.CompressBlockBound(n)
}
func (lc *Lz4Compressor) CompressBufferCollection(buffer []byte){
memPool.ReleaseBytes(buffer)
}
func (lc *Lz4Compressor) UnCompressBufferCollection(buffer []byte) {
memPool.ReleaseBytes(buffer)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package rpc; package rpc;
option go_package = "./rpc"; option go_package = ".;rpc";
message NodeInfo{ message NodeInfo{
int32 NodeId = 1; int32 NodeId = 1;
@@ -8,7 +8,8 @@ message NodeInfo{
string ListenAddr = 3; string ListenAddr = 3;
uint32 MaxRpcParamLen = 4; uint32 MaxRpcParamLen = 4;
bool Private = 5; bool Private = 5;
repeated string PublicServiceList = 6; bool Retire = 6;
repeated string PublicServiceList = 7;
} }
//Client->Master //Client->Master
@@ -24,6 +25,12 @@ message SubscribeDiscoverNotify{
repeated NodeInfo nodeInfo = 4; repeated NodeInfo nodeInfo = 4;
} }
//Client->Master
message NodeRetireReq{
NodeInfo nodeInfo = 1;
}
//Master->Client //Master->Client
message Empty{ message Empty{
} }

View File

@@ -1,106 +0,0 @@
package rpc
import (
"github.com/duanhf2012/origin/util/sync"
"github.com/gogo/protobuf/proto"
"fmt"
)
type GoGoPBProcessor struct {
}
var rpcGoGoPbResponseDataPool =sync.NewPool(make(chan interface{},10240), func()interface{}{
return &GoGoPBRpcResponseData{}
})
var rpcGoGoPbRequestDataPool =sync.NewPool(make(chan interface{},10240), func()interface{}{
return &GoGoPBRpcRequestData{}
})
func (slf *GoGoPBRpcRequestData) MakeRequest(seq uint64,rpcMethodId uint32,serviceMethod string,noReply bool,inParam []byte) *GoGoPBRpcRequestData{
slf.Seq = seq
slf.RpcMethodId = rpcMethodId
slf.ServiceMethod = serviceMethod
slf.NoReply = noReply
slf.InParam = inParam
return slf
}
func (slf *GoGoPBRpcResponseData) MakeRespone(seq uint64,err RpcError,reply []byte) *GoGoPBRpcResponseData{
slf.Seq = seq
slf.Error = err.Error()
slf.Reply = reply
return slf
}
func (slf *GoGoPBProcessor) Marshal(v interface{}) ([]byte, error){
return proto.Marshal(v.(proto.Message))
}
func (slf *GoGoPBProcessor) Unmarshal(data []byte, msg interface{}) error{
protoMsg,ok := msg.(proto.Message)
if ok == false {
return fmt.Errorf("%+v is not of proto.Message type",msg)
}
return proto.Unmarshal(data, protoMsg)
}
func (slf *GoGoPBProcessor) MakeRpcRequest(seq uint64,rpcMethodId uint32,serviceMethod string,noReply bool,inParam []byte) IRpcRequestData{
pGogoPbRpcRequestData := rpcGoGoPbRequestDataPool.Get().(*GoGoPBRpcRequestData)
pGogoPbRpcRequestData.MakeRequest(seq,rpcMethodId,serviceMethod,noReply,inParam)
return pGogoPbRpcRequestData
}
func (slf *GoGoPBProcessor) MakeRpcResponse(seq uint64,err RpcError,reply []byte) IRpcResponseData {
pGoGoPBRpcResponseData := rpcGoGoPbResponseDataPool.Get().(*GoGoPBRpcResponseData)
pGoGoPBRpcResponseData.MakeRespone(seq,err,reply)
return pGoGoPBRpcResponseData
}
func (slf *GoGoPBProcessor) ReleaseRpcRequest(rpcRequestData IRpcRequestData){
rpcGoGoPbRequestDataPool.Put(rpcRequestData)
}
func (slf *GoGoPBProcessor) ReleaseRpcResponse(rpcResponseData IRpcResponseData){
rpcGoGoPbResponseDataPool.Put(rpcResponseData)
}
func (slf *GoGoPBProcessor) IsParse(param interface{}) bool {
_,ok := param.(proto.Message)
return ok
}
func (slf *GoGoPBProcessor) GetProcessorType() RpcProcessorType{
return RpcProcessorGoGoPB
}
func (slf *GoGoPBProcessor) Clone(src interface{}) (interface{},error){
srcMsg,ok := src.(proto.Message)
if ok == false {
return nil,fmt.Errorf("param is not of proto.message type")
}
return proto.Clone(srcMsg),nil
}
func (slf *GoGoPBRpcRequestData) IsNoReply() bool{
return slf.GetNoReply()
}
func (slf *GoGoPBRpcResponseData) GetErr() *RpcError {
if slf.GetError() == "" {
return nil
}
err := RpcError(slf.GetError())
return &err
}

View File

@@ -1,769 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: gogorpc.proto
package rpc
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type GoGoPBRpcRequestData struct {
Seq uint64 `protobuf:"varint,1,opt,name=Seq,proto3" json:"Seq,omitempty"`
RpcMethodId uint32 `protobuf:"varint,2,opt,name=RpcMethodId,proto3" json:"RpcMethodId,omitempty"`
ServiceMethod string `protobuf:"bytes,3,opt,name=ServiceMethod,proto3" json:"ServiceMethod,omitempty"`
NoReply bool `protobuf:"varint,4,opt,name=NoReply,proto3" json:"NoReply,omitempty"`
InParam []byte `protobuf:"bytes,5,opt,name=InParam,proto3" json:"InParam,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GoGoPBRpcRequestData) Reset() { *m = GoGoPBRpcRequestData{} }
func (m *GoGoPBRpcRequestData) String() string { return proto.CompactTextString(m) }
func (*GoGoPBRpcRequestData) ProtoMessage() {}
func (*GoGoPBRpcRequestData) Descriptor() ([]byte, []int) {
return fileDescriptor_d0e25d3af112ec8f, []int{0}
}
func (m *GoGoPBRpcRequestData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GoGoPBRpcRequestData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GoGoPBRpcRequestData.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GoGoPBRpcRequestData) XXX_Merge(src proto.Message) {
xxx_messageInfo_GoGoPBRpcRequestData.Merge(m, src)
}
func (m *GoGoPBRpcRequestData) XXX_Size() int {
return m.Size()
}
func (m *GoGoPBRpcRequestData) XXX_DiscardUnknown() {
xxx_messageInfo_GoGoPBRpcRequestData.DiscardUnknown(m)
}
var xxx_messageInfo_GoGoPBRpcRequestData proto.InternalMessageInfo
func (m *GoGoPBRpcRequestData) GetSeq() uint64 {
if m != nil {
return m.Seq
}
return 0
}
func (m *GoGoPBRpcRequestData) GetRpcMethodId() uint32 {
if m != nil {
return m.RpcMethodId
}
return 0
}
func (m *GoGoPBRpcRequestData) GetServiceMethod() string {
if m != nil {
return m.ServiceMethod
}
return ""
}
func (m *GoGoPBRpcRequestData) GetNoReply() bool {
if m != nil {
return m.NoReply
}
return false
}
func (m *GoGoPBRpcRequestData) GetInParam() []byte {
if m != nil {
return m.InParam
}
return nil
}
type GoGoPBRpcResponseData struct {
Seq uint64 `protobuf:"varint,1,opt,name=Seq,proto3" json:"Seq,omitempty"`
Error string `protobuf:"bytes,2,opt,name=Error,proto3" json:"Error,omitempty"`
Reply []byte `protobuf:"bytes,3,opt,name=Reply,proto3" json:"Reply,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GoGoPBRpcResponseData) Reset() { *m = GoGoPBRpcResponseData{} }
func (m *GoGoPBRpcResponseData) String() string { return proto.CompactTextString(m) }
func (*GoGoPBRpcResponseData) ProtoMessage() {}
func (*GoGoPBRpcResponseData) Descriptor() ([]byte, []int) {
return fileDescriptor_d0e25d3af112ec8f, []int{1}
}
func (m *GoGoPBRpcResponseData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GoGoPBRpcResponseData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GoGoPBRpcResponseData.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GoGoPBRpcResponseData) XXX_Merge(src proto.Message) {
xxx_messageInfo_GoGoPBRpcResponseData.Merge(m, src)
}
func (m *GoGoPBRpcResponseData) XXX_Size() int {
return m.Size()
}
func (m *GoGoPBRpcResponseData) XXX_DiscardUnknown() {
xxx_messageInfo_GoGoPBRpcResponseData.DiscardUnknown(m)
}
var xxx_messageInfo_GoGoPBRpcResponseData proto.InternalMessageInfo
func (m *GoGoPBRpcResponseData) GetSeq() uint64 {
if m != nil {
return m.Seq
}
return 0
}
func (m *GoGoPBRpcResponseData) GetError() string {
if m != nil {
return m.Error
}
return ""
}
func (m *GoGoPBRpcResponseData) GetReply() []byte {
if m != nil {
return m.Reply
}
return nil
}
func init() {
proto.RegisterType((*GoGoPBRpcRequestData)(nil), "rpc.GoGoPBRpcRequestData")
proto.RegisterType((*GoGoPBRpcResponseData)(nil), "rpc.GoGoPBRpcResponseData")
}
func init() { proto.RegisterFile("gogorpc.proto", fileDescriptor_d0e25d3af112ec8f) }
var fileDescriptor_d0e25d3af112ec8f = []byte{
// 233 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4d, 0xcf, 0x4f, 0xcf,
0x2f, 0x2a, 0x48, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2e, 0x2a, 0x48, 0x56, 0x5a,
0xc2, 0xc8, 0x25, 0xe2, 0x9e, 0xef, 0x9e, 0x1f, 0xe0, 0x14, 0x54, 0x90, 0x1c, 0x94, 0x5a, 0x58,
0x9a, 0x5a, 0x5c, 0xe2, 0x92, 0x58, 0x92, 0x28, 0x24, 0xc0, 0xc5, 0x1c, 0x9c, 0x5a, 0x28, 0xc1,
0xa8, 0xc0, 0xa8, 0xc1, 0x12, 0x04, 0x62, 0x0a, 0x29, 0x70, 0x71, 0x07, 0x15, 0x24, 0xfb, 0xa6,
0x96, 0x64, 0xe4, 0xa7, 0x78, 0xa6, 0x48, 0x30, 0x29, 0x30, 0x6a, 0xf0, 0x06, 0x21, 0x0b, 0x09,
0xa9, 0x70, 0xf1, 0x06, 0xa7, 0x16, 0x95, 0x65, 0x26, 0xa7, 0x42, 0x84, 0x24, 0x98, 0x15, 0x18,
0x35, 0x38, 0x83, 0x50, 0x05, 0x85, 0x24, 0xb8, 0xd8, 0xfd, 0xf2, 0x83, 0x52, 0x0b, 0x72, 0x2a,
0x25, 0x58, 0x14, 0x18, 0x35, 0x38, 0x82, 0x60, 0x5c, 0x90, 0x8c, 0x67, 0x5e, 0x40, 0x62, 0x51,
0x62, 0xae, 0x04, 0xab, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x8c, 0xab, 0x14, 0xca, 0x25, 0x8a, 0xe4,
0xca, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0x1c, 0xce, 0x14, 0xe1, 0x62, 0x75, 0x2d, 0x2a, 0xca,
0x2f, 0x02, 0x3b, 0x90, 0x33, 0x08, 0xc2, 0x01, 0x89, 0x42, 0xac, 0x64, 0x06, 0x1b, 0x0c, 0xe1,
0x38, 0x09, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x51,
0xac, 0x7a, 0xfa, 0x45, 0x05, 0xc9, 0x49, 0x6c, 0xe0, 0xe0, 0x31, 0x06, 0x04, 0x00, 0x00, 0xff,
0xff, 0x26, 0xcf, 0x31, 0x39, 0x2f, 0x01, 0x00, 0x00,
}
func (m *GoGoPBRpcRequestData) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GoGoPBRpcRequestData) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GoGoPBRpcRequestData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.InParam) > 0 {
i -= len(m.InParam)
copy(dAtA[i:], m.InParam)
i = encodeVarintGogorpc(dAtA, i, uint64(len(m.InParam)))
i--
dAtA[i] = 0x2a
}
if m.NoReply {
i--
if m.NoReply {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x20
}
if len(m.ServiceMethod) > 0 {
i -= len(m.ServiceMethod)
copy(dAtA[i:], m.ServiceMethod)
i = encodeVarintGogorpc(dAtA, i, uint64(len(m.ServiceMethod)))
i--
dAtA[i] = 0x1a
}
if m.RpcMethodId != 0 {
i = encodeVarintGogorpc(dAtA, i, uint64(m.RpcMethodId))
i--
dAtA[i] = 0x10
}
if m.Seq != 0 {
i = encodeVarintGogorpc(dAtA, i, uint64(m.Seq))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *GoGoPBRpcResponseData) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GoGoPBRpcResponseData) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GoGoPBRpcResponseData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Reply) > 0 {
i -= len(m.Reply)
copy(dAtA[i:], m.Reply)
i = encodeVarintGogorpc(dAtA, i, uint64(len(m.Reply)))
i--
dAtA[i] = 0x1a
}
if len(m.Error) > 0 {
i -= len(m.Error)
copy(dAtA[i:], m.Error)
i = encodeVarintGogorpc(dAtA, i, uint64(len(m.Error)))
i--
dAtA[i] = 0x12
}
if m.Seq != 0 {
i = encodeVarintGogorpc(dAtA, i, uint64(m.Seq))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintGogorpc(dAtA []byte, offset int, v uint64) int {
offset -= sovGogorpc(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GoGoPBRpcRequestData) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Seq != 0 {
n += 1 + sovGogorpc(uint64(m.Seq))
}
if m.RpcMethodId != 0 {
n += 1 + sovGogorpc(uint64(m.RpcMethodId))
}
l = len(m.ServiceMethod)
if l > 0 {
n += 1 + l + sovGogorpc(uint64(l))
}
if m.NoReply {
n += 2
}
l = len(m.InParam)
if l > 0 {
n += 1 + l + sovGogorpc(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *GoGoPBRpcResponseData) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Seq != 0 {
n += 1 + sovGogorpc(uint64(m.Seq))
}
l = len(m.Error)
if l > 0 {
n += 1 + l + sovGogorpc(uint64(l))
}
l = len(m.Reply)
if l > 0 {
n += 1 + l + sovGogorpc(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovGogorpc(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGogorpc(x uint64) (n int) {
return sovGogorpc(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GoGoPBRpcRequestData) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GoGoPBRpcRequestData: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GoGoPBRpcRequestData: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType)
}
m.Seq = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seq |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RpcMethodId", wireType)
}
m.RpcMethodId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RpcMethodId |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ServiceMethod", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGogorpc
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGogorpc
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ServiceMethod = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NoReply", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.NoReply = bool(v != 0)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field InParam", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGogorpc
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGogorpc
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.InParam = append(m.InParam[:0], dAtA[iNdEx:postIndex]...)
if m.InParam == nil {
m.InParam = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGogorpc(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGogorpc
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGogorpc
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GoGoPBRpcResponseData) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GoGoPBRpcResponseData: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GoGoPBRpcResponseData: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType)
}
m.Seq = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seq |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGogorpc
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGogorpc
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Reply", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogorpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthGogorpc
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGogorpc
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Reply = append(m.Reply[:0], dAtA[iNdEx:postIndex]...)
if m.Reply == nil {
m.Reply = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGogorpc(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGogorpc
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGogorpc
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGogorpc(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogorpc
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogorpc
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogorpc
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGogorpc
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGogorpc
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGogorpc
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGogorpc = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGogorpc = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGogorpc = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -7,6 +7,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"sync/atomic" "sync/atomic"
"time"
) )
//本结点的Client //本结点的Client
@@ -36,13 +37,13 @@ func (lc *LClient) SetConn(conn *network.TCPConn){
func (lc *LClient) Close(waitDone bool){ func (lc *LClient) Close(waitDone bool){
} }
func (lc *LClient) Go(rpcHandler IRpcHandler,noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call { func (lc *LClient) Go(timeout time.Duration,rpcHandler IRpcHandler,noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call {
pLocalRpcServer := rpcHandler.GetRpcServer()() pLocalRpcServer := rpcHandler.GetRpcServer()()
//判断是否是同一服务 //判断是否是同一服务
findIndex := strings.Index(serviceMethod, ".") findIndex := strings.Index(serviceMethod, ".")
if findIndex == -1 { if findIndex == -1 {
sErr := errors.New("Call serviceMethod " + serviceMethod + " is error!") sErr := errors.New("Call serviceMethod " + serviceMethod + " is error!")
log.SError(sErr.Error()) log.Error("call rpc fail",log.String("error",sErr.Error()))
call := MakeCall() call := MakeCall()
call.DoError(sErr) call.DoError(sErr)
@@ -65,19 +66,20 @@ func (lc *LClient) Go(rpcHandler IRpcHandler,noReply bool, serviceMethod string,
} }
//其他的rpcHandler的处理器 //其他的rpcHandler的处理器
return pLocalRpcServer.selfNodeRpcHandlerGo(nil, lc.selfClient, noReply, serviceName, 0, serviceMethod, args, reply, nil) return pLocalRpcServer.selfNodeRpcHandlerGo(timeout,nil, lc.selfClient, noReply, serviceName, 0, serviceMethod, args, reply, nil)
} }
func (rc *LClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceName string, rawArgs []byte, reply interface{}) *Call { func (rc *LClient) RawGo(timeout time.Duration,rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceName string, rawArgs []byte, reply interface{}) *Call {
pLocalRpcServer := rpcHandler.GetRpcServer()() pLocalRpcServer := rpcHandler.GetRpcServer()()
call := MakeCall()
call.ServiceMethod = serviceName
call.Reply = reply
//服务自我调用 //服务自我调用
if serviceName == rpcHandler.GetName() { if serviceName == rpcHandler.GetName() {
call := MakeCall()
call.ServiceMethod = serviceName
call.Reply = reply
call.TimeOut = timeout
err := pLocalRpcServer.myselfRpcHandlerGo(rc.selfClient,serviceName, serviceName, rawArgs, requestHandlerNull,nil) err := pLocalRpcServer.myselfRpcHandlerGo(rc.selfClient,serviceName, serviceName, rawArgs, requestHandlerNull,nil)
call.Err = err call.Err = err
call.done <- call call.done <- call
@@ -86,11 +88,11 @@ func (rc *LClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
} }
//其他的rpcHandler的处理器 //其他的rpcHandler的处理器
return pLocalRpcServer.selfNodeRpcHandlerGo(processor,rc.selfClient, true, serviceName, rpcMethodId, serviceName, nil, nil, rawArgs) return pLocalRpcServer.selfNodeRpcHandlerGo(timeout,processor,rc.selfClient, true, serviceName, rpcMethodId, serviceName, nil, nil, rawArgs)
} }
func (lc *LClient) AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, reply interface{}) error { func (lc *LClient) AsyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, reply interface{},cancelable bool) (CancelRpc,error) {
pLocalRpcServer := rpcHandler.GetRpcServer()() pLocalRpcServer := rpcHandler.GetRpcServer()()
//判断是否是同一服务 //判断是否是同一服务
@@ -98,23 +100,23 @@ func (lc *LClient) AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
if findIndex == -1 { if findIndex == -1 {
err := errors.New("Call serviceMethod " + serviceMethod + " is error!") err := errors.New("Call serviceMethod " + serviceMethod + " is error!")
callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)}) callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
log.SError(err.Error()) log.Error("serviceMethod format is error",log.String("error",err.Error()))
return nil return emptyCancelRpc,nil
} }
serviceName := serviceMethod[:findIndex] serviceName := serviceMethod[:findIndex]
//调用自己rpcHandler处理器 //调用自己rpcHandler处理器
if serviceName == rpcHandler.GetName() { //自己服务调用 if serviceName == rpcHandler.GetName() { //自己服务调用
return pLocalRpcServer.myselfRpcHandlerGo(lc.selfClient,serviceName, serviceMethod, args,callback ,reply) return emptyCancelRpc,pLocalRpcServer.myselfRpcHandlerGo(lc.selfClient,serviceName, serviceMethod, args,callback ,reply)
} }
//其他的rpcHandler的处理器 //其他的rpcHandler的处理器
err := pLocalRpcServer.selfNodeRpcHandlerAsyncGo(lc.selfClient, rpcHandler, false, serviceName, serviceMethod, args, reply, callback) calcelRpc,err := pLocalRpcServer.selfNodeRpcHandlerAsyncGo(timeout,lc.selfClient, rpcHandler, false, serviceName, serviceMethod, args, reply, callback,cancelable)
if err != nil { if err != nil {
callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)}) callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
} }
return nil return calcelRpc,nil
} }
func NewLClient(nodeId int) *Client{ func NewLClient(nodeId int) *Client{

File diff suppressed because it is too large Load Diff

106
rpc/pbprocessor.go Normal file
View File

@@ -0,0 +1,106 @@
package rpc
import (
"github.com/duanhf2012/origin/util/sync"
"google.golang.org/protobuf/proto"
"fmt"
)
type PBProcessor struct {
}
var rpcPbResponseDataPool =sync.NewPool(make(chan interface{},10240), func()interface{}{
return &PBRpcResponseData{}
})
var rpcPbRequestDataPool =sync.NewPool(make(chan interface{},10240), func()interface{}{
return &PBRpcRequestData{}
})
func (slf *PBRpcRequestData) MakeRequest(seq uint64,rpcMethodId uint32,serviceMethod string,noReply bool,inParam []byte) *PBRpcRequestData{
slf.Seq = seq
slf.RpcMethodId = rpcMethodId
slf.ServiceMethod = serviceMethod
slf.NoReply = noReply
slf.InParam = inParam
return slf
}
func (slf *PBRpcResponseData) MakeRespone(seq uint64,err RpcError,reply []byte) *PBRpcResponseData{
slf.Seq = seq
slf.Error = err.Error()
slf.Reply = reply
return slf
}
func (slf *PBProcessor) Marshal(v interface{}) ([]byte, error){
return proto.Marshal(v.(proto.Message))
}
func (slf *PBProcessor) Unmarshal(data []byte, msg interface{}) error{
protoMsg,ok := msg.(proto.Message)
if ok == false {
return fmt.Errorf("%+v is not of proto.Message type",msg)
}
return proto.Unmarshal(data, protoMsg)
}
func (slf *PBProcessor) MakeRpcRequest(seq uint64,rpcMethodId uint32,serviceMethod string,noReply bool,inParam []byte) IRpcRequestData{
pGogoPbRpcRequestData := rpcPbRequestDataPool.Get().(*PBRpcRequestData)
pGogoPbRpcRequestData.MakeRequest(seq,rpcMethodId,serviceMethod,noReply,inParam)
return pGogoPbRpcRequestData
}
func (slf *PBProcessor) MakeRpcResponse(seq uint64,err RpcError,reply []byte) IRpcResponseData {
pPBRpcResponseData := rpcPbResponseDataPool.Get().(*PBRpcResponseData)
pPBRpcResponseData.MakeRespone(seq,err,reply)
return pPBRpcResponseData
}
func (slf *PBProcessor) ReleaseRpcRequest(rpcRequestData IRpcRequestData){
rpcPbRequestDataPool.Put(rpcRequestData)
}
func (slf *PBProcessor) ReleaseRpcResponse(rpcResponseData IRpcResponseData){
rpcPbResponseDataPool.Put(rpcResponseData)
}
func (slf *PBProcessor) IsParse(param interface{}) bool {
_,ok := param.(proto.Message)
return ok
}
func (slf *PBProcessor) GetProcessorType() RpcProcessorType{
return RpcProcessorPB
}
func (slf *PBProcessor) Clone(src interface{}) (interface{},error){
srcMsg,ok := src.(proto.Message)
if ok == false {
return nil,fmt.Errorf("param is not of proto.message type")
}
return proto.Clone(srcMsg),nil
}
func (slf *PBRpcRequestData) IsNoReply() bool{
return slf.GetNoReply()
}
func (slf *PBRpcResponseData) GetErr() *RpcError {
if slf.GetError() == "" {
return nil
}
err := RpcError(slf.GetError())
return &err
}

263
rpc/protorpc.pb.go Normal file
View File

@@ -0,0 +1,263 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v3.11.4
// source: test/rpc/protorpc.proto
package rpc
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type PBRpcRequestData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Seq uint64 `protobuf:"varint,1,opt,name=Seq,proto3" json:"Seq,omitempty"`
RpcMethodId uint32 `protobuf:"varint,2,opt,name=RpcMethodId,proto3" json:"RpcMethodId,omitempty"`
ServiceMethod string `protobuf:"bytes,3,opt,name=ServiceMethod,proto3" json:"ServiceMethod,omitempty"`
NoReply bool `protobuf:"varint,4,opt,name=NoReply,proto3" json:"NoReply,omitempty"`
InParam []byte `protobuf:"bytes,5,opt,name=InParam,proto3" json:"InParam,omitempty"`
}
func (x *PBRpcRequestData) Reset() {
*x = PBRpcRequestData{}
if protoimpl.UnsafeEnabled {
mi := &file_test_rpc_protorpc_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PBRpcRequestData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PBRpcRequestData) ProtoMessage() {}
func (x *PBRpcRequestData) ProtoReflect() protoreflect.Message {
mi := &file_test_rpc_protorpc_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PBRpcRequestData.ProtoReflect.Descriptor instead.
func (*PBRpcRequestData) Descriptor() ([]byte, []int) {
return file_test_rpc_protorpc_proto_rawDescGZIP(), []int{0}
}
func (x *PBRpcRequestData) GetSeq() uint64 {
if x != nil {
return x.Seq
}
return 0
}
func (x *PBRpcRequestData) GetRpcMethodId() uint32 {
if x != nil {
return x.RpcMethodId
}
return 0
}
func (x *PBRpcRequestData) GetServiceMethod() string {
if x != nil {
return x.ServiceMethod
}
return ""
}
func (x *PBRpcRequestData) GetNoReply() bool {
if x != nil {
return x.NoReply
}
return false
}
func (x *PBRpcRequestData) GetInParam() []byte {
if x != nil {
return x.InParam
}
return nil
}
type PBRpcResponseData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Seq uint64 `protobuf:"varint,1,opt,name=Seq,proto3" json:"Seq,omitempty"`
Error string `protobuf:"bytes,2,opt,name=Error,proto3" json:"Error,omitempty"`
Reply []byte `protobuf:"bytes,3,opt,name=Reply,proto3" json:"Reply,omitempty"`
}
func (x *PBRpcResponseData) Reset() {
*x = PBRpcResponseData{}
if protoimpl.UnsafeEnabled {
mi := &file_test_rpc_protorpc_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PBRpcResponseData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PBRpcResponseData) ProtoMessage() {}
func (x *PBRpcResponseData) ProtoReflect() protoreflect.Message {
mi := &file_test_rpc_protorpc_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PBRpcResponseData.ProtoReflect.Descriptor instead.
func (*PBRpcResponseData) Descriptor() ([]byte, []int) {
return file_test_rpc_protorpc_proto_rawDescGZIP(), []int{1}
}
func (x *PBRpcResponseData) GetSeq() uint64 {
if x != nil {
return x.Seq
}
return 0
}
func (x *PBRpcResponseData) GetError() string {
if x != nil {
return x.Error
}
return ""
}
func (x *PBRpcResponseData) GetReply() []byte {
if x != nil {
return x.Reply
}
return nil
}
var File_test_rpc_protorpc_proto protoreflect.FileDescriptor
var file_test_rpc_protorpc_proto_rawDesc = []byte{
0x0a, 0x17, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x72, 0x70, 0x63, 0x22, 0xa0,
0x01, 0x0a, 0x10, 0x50, 0x42, 0x52, 0x70, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44,
0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x03, 0x53, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x70, 0x63, 0x4d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x52, 0x70, 0x63, 0x4d,
0x65, 0x74, 0x68, 0x6f, 0x64, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x18, 0x0a,
0x07, 0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x50, 0x61, 0x72,
0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x49, 0x6e, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x22, 0x51, 0x0a, 0x11, 0x50, 0x42, 0x52, 0x70, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x65, 0x71, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x03, 0x53, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f,
0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x14,
0x0a, 0x05, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_test_rpc_protorpc_proto_rawDescOnce sync.Once
file_test_rpc_protorpc_proto_rawDescData = file_test_rpc_protorpc_proto_rawDesc
)
func file_test_rpc_protorpc_proto_rawDescGZIP() []byte {
file_test_rpc_protorpc_proto_rawDescOnce.Do(func() {
file_test_rpc_protorpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_rpc_protorpc_proto_rawDescData)
})
return file_test_rpc_protorpc_proto_rawDescData
}
var file_test_rpc_protorpc_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_test_rpc_protorpc_proto_goTypes = []interface{}{
(*PBRpcRequestData)(nil), // 0: rpc.PBRpcRequestData
(*PBRpcResponseData)(nil), // 1: rpc.PBRpcResponseData
}
var file_test_rpc_protorpc_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_test_rpc_protorpc_proto_init() }
func file_test_rpc_protorpc_proto_init() {
if File_test_rpc_protorpc_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_test_rpc_protorpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PBRpcRequestData); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_test_rpc_protorpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PBRpcResponseData); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_test_rpc_protorpc_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_test_rpc_protorpc_proto_goTypes,
DependencyIndexes: file_test_rpc_protorpc_proto_depIdxs,
MessageInfos: file_test_rpc_protorpc_proto_msgTypes,
}.Build()
File_test_rpc_protorpc_proto = out.File
file_test_rpc_protorpc_proto_rawDesc = nil
file_test_rpc_protorpc_proto_goTypes = nil
file_test_rpc_protorpc_proto_depIdxs = nil
}

View File

@@ -1,8 +1,8 @@
syntax = "proto3"; syntax = "proto3";
package rpc; package rpc;
option go_package = "./rpc"; option go_package = ".;rpc";
message GoGoPBRpcRequestData{ message PBRpcRequestData{
uint64 Seq = 1; uint64 Seq = 1;
uint32 RpcMethodId = 2; uint32 RpcMethodId = 2;
string ServiceMethod = 3; string ServiceMethod = 3;
@@ -10,7 +10,7 @@ message GoGoPBRpcRequestData{
bytes InParam = 5; bytes InParam = 5;
} }
message GoGoPBRpcResponseData{ message PBRpcResponseData{
uint64 Seq = 1; uint64 Seq = 1;
string Error = 2; string Error = 2;
bytes Reply = 3; bytes Reply = 3;

File diff suppressed because it is too large Load Diff

View File

@@ -9,10 +9,12 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"sync/atomic" "sync/atomic"
"time"
) )
//跨结点连接的Client //跨结点连接的Client
type RClient struct { type RClient struct {
compressBytesLen int
selfClient *Client selfClient *Client
network.TCPClient network.TCPClient
conn *network.TCPConn conn *network.TCPConn
@@ -40,25 +42,25 @@ func (rc *RClient) SetConn(conn *network.TCPConn){
rc.Unlock() rc.Unlock()
} }
func (rc *RClient) Go(rpcHandler IRpcHandler,noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call { func (rc *RClient) Go(timeout time.Duration,rpcHandler IRpcHandler,noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call {
_, processor := GetProcessorType(args) _, processor := GetProcessorType(args)
InParam, err := processor.Marshal(args) InParam, err := processor.Marshal(args)
if err != nil { if err != nil {
log.SError(err.Error()) log.Error("Marshal is fail",log.ErrorAttr("error",err))
call := MakeCall() call := MakeCall()
call.DoError(err) call.DoError(err)
return call return call
} }
return rc.RawGo(rpcHandler,processor, noReply, 0, serviceMethod, InParam, reply) return rc.RawGo(timeout,rpcHandler,processor, noReply, 0, serviceMethod, InParam, reply)
} }
func (rc *RClient) RawGo(timeout time.Duration,rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call {
func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call {
call := MakeCall() call := MakeCall()
call.ServiceMethod = serviceMethod call.ServiceMethod = serviceMethod
call.Reply = reply call.Reply = reply
call.Seq = rc.selfClient.generateSeq() call.Seq = rc.selfClient.generateSeq()
call.TimeOut = timeout
request := MakeRpcRequest(processor, call.Seq, rpcMethodId, serviceMethod, noReply, rawArgs) request := MakeRpcRequest(processor, call.Seq, rpcMethodId, serviceMethod, noReply, rawArgs)
bytes, err := processor.Marshal(request.RpcRequestData) bytes, err := processor.Marshal(request.RpcRequestData)
@@ -66,7 +68,7 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
if err != nil { if err != nil {
call.Seq = 0 call.Seq = 0
log.SError(err.Error()) log.Error("marshal is fail",log.String("error",err.Error()))
call.DoError(err) call.DoError(err)
return call return call
} }
@@ -75,21 +77,39 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
if conn == nil || conn.IsConnected()==false { if conn == nil || conn.IsConnected()==false {
call.Seq = 0 call.Seq = 0
sErr := errors.New(serviceMethod + " was called failed,rpc client is disconnect") sErr := errors.New(serviceMethod + " was called failed,rpc client is disconnect")
log.SError(sErr.Error()) log.Error("conn is disconnect",log.String("error",sErr.Error()))
call.DoError(sErr) call.DoError(sErr)
return call return call
} }
var compressBuff[]byte
bCompress := uint8(0)
if rc.compressBytesLen > 0 && len(bytes) >= rc.compressBytesLen {
var cErr error
compressBuff,cErr = compressor.CompressBlock(bytes)
if cErr != nil {
call.Seq = 0
log.Error("compress fail",log.String("error",cErr.Error()))
call.DoError(cErr)
return call
}
if len(compressBuff) < len(bytes) {
bytes = compressBuff
bCompress = 1<<7
}
}
if noReply == false { if noReply == false {
rc.selfClient.AddPending(call) rc.selfClient.AddPending(call)
} }
err = conn.WriteMsg([]byte{uint8(processor.GetProcessorType())}, bytes) err = conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
if cap(compressBuff) >0 {
compressor.CompressBufferCollection(compressBuff)
}
if err != nil { if err != nil {
rc.selfClient.RemovePending(call.Seq) rc.selfClient.RemovePending(call.Seq)
log.Error("WiteMsg is fail",log.ErrorAttr("error",err))
log.SError(err.Error())
call.Seq = 0 call.Seq = 0
call.DoError(err) call.DoError(err)
} }
@@ -98,20 +118,20 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
} }
func (rc *RClient) AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{}) error { func (rc *RClient) AsyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{},cancelable bool) (CancelRpc,error) {
err := rc.asyncCall(rpcHandler, serviceMethod, callback, args, replyParam) cancelRpc,err := rc.asyncCall(timeout,rpcHandler, serviceMethod, callback, args, replyParam,cancelable)
if err != nil { if err != nil {
callback.Call([]reflect.Value{reflect.ValueOf(replyParam), reflect.ValueOf(err)}) callback.Call([]reflect.Value{reflect.ValueOf(replyParam), reflect.ValueOf(err)})
} }
return nil return cancelRpc,nil
} }
func (rc *RClient) asyncCall(rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{}) error { func (rc *RClient) asyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{},cancelable bool) (CancelRpc,error) {
processorType, processor := GetProcessorType(args) processorType, processor := GetProcessorType(args)
InParam, herr := processor.Marshal(args) InParam, herr := processor.Marshal(args)
if herr != nil { if herr != nil {
return herr return emptyCancelRpc,herr
} }
seq := rc.selfClient.generateSeq() seq := rc.selfClient.generateSeq()
@@ -119,12 +139,27 @@ func (rc *RClient) asyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
bytes, err := processor.Marshal(request.RpcRequestData) bytes, err := processor.Marshal(request.RpcRequestData)
ReleaseRpcRequest(request) ReleaseRpcRequest(request)
if err != nil { if err != nil {
return err return emptyCancelRpc,err
} }
conn := rc.GetConn() conn := rc.GetConn()
if conn == nil || conn.IsConnected()==false { if conn == nil || conn.IsConnected()==false {
return errors.New("Rpc server is disconnect,call " + serviceMethod) return emptyCancelRpc,errors.New("Rpc server is disconnect,call " + serviceMethod)
}
var compressBuff[]byte
bCompress := uint8(0)
if rc.compressBytesLen>0 &&len(bytes) >= rc.compressBytesLen {
var cErr error
compressBuff,cErr = compressor.CompressBlock(bytes)
if cErr != nil {
return emptyCancelRpc,cErr
}
if len(compressBuff) < len(bytes) {
bytes = compressBuff
bCompress = 1<<7
}
} }
call := MakeCall() call := MakeCall()
@@ -133,16 +168,25 @@ func (rc *RClient) asyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
call.rpcHandler = rpcHandler call.rpcHandler = rpcHandler
call.ServiceMethod = serviceMethod call.ServiceMethod = serviceMethod
call.Seq = seq call.Seq = seq
call.TimeOut = timeout
rc.selfClient.AddPending(call) rc.selfClient.AddPending(call)
err = conn.WriteMsg([]byte{uint8(processorType)}, bytes) err = conn.WriteMsg([]byte{uint8(processorType)|bCompress}, bytes)
if cap(compressBuff) >0 {
compressor.CompressBufferCollection(compressBuff)
}
if err != nil { if err != nil {
rc.selfClient.RemovePending(call.Seq) rc.selfClient.RemovePending(call.Seq)
ReleaseCall(call) ReleaseCall(call)
return err return emptyCancelRpc,err
} }
return nil if cancelable {
rpcCancel := RpcCancel{CallSeq:seq,Cli: rc.selfClient}
return rpcCancel.CancelRpc,nil
}
return emptyCancelRpc,nil
} }
func (rc *RClient) Run() { func (rc *RClient) Run() {
@@ -151,7 +195,7 @@ func (rc *RClient) Run() {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -159,14 +203,15 @@ func (rc *RClient) Run() {
for { for {
bytes, err := rc.conn.ReadMsg() bytes, err := rc.conn.ReadMsg()
if err != nil { if err != nil {
log.SError("rpcClient ", rc.Addr, " ReadMsg error:", err.Error()) log.Error("rclient read msg is failed",log.ErrorAttr("error",err))
return return
} }
processor := GetProcessor(bytes[0]) bCompress := (bytes[0]>>7) > 0
processor := GetProcessor(bytes[0]&0x7f)
if processor == nil { if processor == nil {
rc.conn.ReleaseReadMsg(bytes) rc.conn.ReleaseReadMsg(bytes)
log.SError("rpcClient ", rc.Addr, " ReadMsg head error:", err.Error()) log.Error("cannot find process",log.Uint8("process type",bytes[0]&0x7f))
return return
} }
@@ -174,23 +219,42 @@ func (rc *RClient) Run() {
response := RpcResponse{} response := RpcResponse{}
response.RpcResponseData = processor.MakeRpcResponse(0, "", nil) response.RpcResponseData = processor.MakeRpcResponse(0, "", nil)
err = processor.Unmarshal(bytes[1:], response.RpcResponseData) //解压缩
byteData := bytes[1:]
var compressBuff []byte
if bCompress == true {
var unCompressErr error
compressBuff,unCompressErr = compressor.UncompressBlock(byteData)
if unCompressErr!= nil {
rc.conn.ReleaseReadMsg(bytes)
log.Error("uncompressBlock failed",log.ErrorAttr("error",unCompressErr))
return
}
byteData = compressBuff
}
err = processor.Unmarshal(byteData, response.RpcResponseData)
if cap(compressBuff) > 0 {
compressor.UnCompressBufferCollection(compressBuff)
}
rc.conn.ReleaseReadMsg(bytes) rc.conn.ReleaseReadMsg(bytes)
if err != nil { if err != nil {
processor.ReleaseRpcResponse(response.RpcResponseData) processor.ReleaseRpcResponse(response.RpcResponseData)
log.SError("rpcClient Unmarshal head error:", err.Error()) log.Error("rpcClient Unmarshal head error",log.ErrorAttr("error",err))
continue continue
} }
v := rc.selfClient.RemovePending(response.RpcResponseData.GetSeq()) v := rc.selfClient.RemovePending(response.RpcResponseData.GetSeq())
if v == nil { if v == nil {
log.SError("rpcClient cannot find seq ", response.RpcResponseData.GetSeq(), " in pending") log.Error("rpcClient cannot find seq",log.Uint64("seq",response.RpcResponseData.GetSeq()))
} else { } else {
v.Err = nil v.Err = nil
if len(response.RpcResponseData.GetReply()) > 0 { if len(response.RpcResponseData.GetReply()) > 0 {
err = processor.Unmarshal(response.RpcResponseData.GetReply(), v.Reply) err = processor.Unmarshal(response.RpcResponseData.GetReply(), v.Reply)
if err != nil { if err != nil {
log.SError("rpcClient Unmarshal body error:", err.Error()) log.Error("rpcClient Unmarshal body failed",log.ErrorAttr("error",err))
v.Err = err v.Err = err
} }
} }
@@ -214,14 +278,14 @@ func (rc *RClient) OnClose() {
rc.TriggerRpcConnEvent(false, rc.selfClient.GetClientId(), rc.selfClient.GetNodeId()) rc.TriggerRpcConnEvent(false, rc.selfClient.GetClientId(), rc.selfClient.GetNodeId())
} }
func NewRClient(nodeId int, addr string, maxRpcParamLen uint32,triggerRpcConnEvent TriggerRpcConnEvent) *Client{ func NewRClient(nodeId int, addr string, maxRpcParamLen uint32,compressBytesLen int,triggerRpcConnEvent TriggerRpcConnEvent) *Client{
client := &Client{} client := &Client{}
client.clientId = atomic.AddUint32(&clientSeq, 1) client.clientId = atomic.AddUint32(&clientSeq, 1)
client.nodeId = nodeId client.nodeId = nodeId
client.maxCheckCallRpcCount = DefaultMaxCheckCallRpcCount client.maxCheckCallRpcCount = DefaultMaxCheckCallRpcCount
client.callRpcTimeout = DefaultRpcTimeout client.callRpcTimeout = DefaultRpcTimeout
c:= &RClient{} c:= &RClient{}
c.compressBytesLen = compressBytesLen
c.selfClient = client c.selfClient = client
c.Addr = addr c.Addr = addr
c.ConnectInterval = DefaultConnectInterval c.ConnectInterval = DefaultConnectInterval
@@ -251,18 +315,6 @@ func NewRClient(nodeId int, addr string, maxRpcParamLen uint32,triggerRpcConnEve
func (rc *RClient) Close(waitDone bool) { func (rc *RClient) Close(waitDone bool) {
rc.TCPClient.Close(waitDone) rc.TCPClient.Close(waitDone)
rc.selfClient.cleanPending()
rc.selfClient.pendingLock.Lock()
for {
pElem := rc.selfClient.pendingTimer.Front()
if pElem == nil {
break
}
pCall := pElem.Value.(*Call)
pCall.Err = errors.New("nodeid is disconnect ")
rc.selfClient.makeCallFail(pCall)
}
rc.selfClient.pendingLock.Unlock()
} }

View File

@@ -68,7 +68,16 @@ type Call struct {
connId int connId int
callback *reflect.Value callback *reflect.Value
rpcHandler IRpcHandler rpcHandler IRpcHandler
callTime time.Time TimeOut time.Duration
}
type RpcCancel struct {
Cli *Client
CallSeq uint64
}
func (rc *RpcCancel) CancelRpc(){
rc.Cli.RemovePending(rc.CallSeq)
} }
func (slf *RpcRequest) Clear() *RpcRequest{ func (slf *RpcRequest) Clear() *RpcRequest{
@@ -124,6 +133,8 @@ func (call *Call) Clear() *Call{
call.connId = 0 call.connId = 0
call.callback = nil call.callback = nil
call.rpcHandler = nil call.rpcHandler = nil
call.TimeOut = 0
return call return call
} }

View File

@@ -9,11 +9,12 @@ import (
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
"time"
) )
const maxClusterNode int = 128 const maxClusterNode int = 128
type FuncRpcClient func(nodeId int, serviceMethod string, client []*Client) (error, int) type FuncRpcClient func(nodeId int, serviceMethod string,filterRetire bool, client []*Client) (error, int)
type FuncRpcServer func() *Server type FuncRpcServer func() *Server
@@ -72,9 +73,12 @@ type INodeListener interface {
type IDiscoveryServiceListener interface { type IDiscoveryServiceListener interface {
OnDiscoveryService(nodeId int, serviceName []string) OnDiscoveryService(nodeId int, serviceName []string)
OnUnDiscoveryService(nodeId int, serviceName []string) OnUnDiscoveryService(nodeId int)
} }
type CancelRpc func()
func emptyCancelRpc(){}
type IRpcHandler interface { type IRpcHandler interface {
IRpcHandlerChannel IRpcHandlerChannel
GetName() string GetName() string
@@ -83,11 +87,18 @@ type IRpcHandler interface {
HandlerRpcRequest(request *RpcRequest) HandlerRpcRequest(request *RpcRequest)
HandlerRpcResponseCB(call *Call) HandlerRpcResponseCB(call *Call)
CallMethod(client *Client,ServiceMethod string, param interface{},callBack reflect.Value, reply interface{}) error CallMethod(client *Client,ServiceMethod string, param interface{},callBack reflect.Value, reply interface{}) error
AsyncCall(serviceMethod string, args interface{}, callback interface{}) error
Call(serviceMethod string, args interface{}, reply interface{}) error Call(serviceMethod string, args interface{}, reply interface{}) error
Go(serviceMethod string, args interface{}) error
AsyncCallNode(nodeId int, serviceMethod string, args interface{}, callback interface{}) error
CallNode(nodeId int, serviceMethod string, args interface{}, reply interface{}) error CallNode(nodeId int, serviceMethod string, args interface{}, reply interface{}) error
AsyncCall(serviceMethod string, args interface{}, callback interface{}) error
AsyncCallNode(nodeId int, serviceMethod string, args interface{}, callback interface{}) error
CallWithTimeout(timeout time.Duration,serviceMethod string, args interface{}, reply interface{}) error
CallNodeWithTimeout(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, reply interface{}) error
AsyncCallWithTimeout(timeout time.Duration,serviceMethod string, args interface{}, callback interface{}) (CancelRpc,error)
AsyncCallNodeWithTimeout(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, callback interface{}) (CancelRpc,error)
Go(serviceMethod string, args interface{}) error
GoNode(nodeId int, serviceMethod string, args interface{}) error GoNode(nodeId int, serviceMethod string, args interface{}) error
RawGoNode(rpcProcessorType RpcProcessorType, nodeId int, rpcMethodId uint32, serviceName string, rawArgs []byte) error RawGoNode(rpcProcessorType RpcProcessorType, nodeId int, rpcMethodId uint32, serviceName string, rawArgs []byte) error
CastGo(serviceMethod string, args interface{}) error CastGo(serviceMethod string, args interface{}) error
@@ -204,7 +215,7 @@ func (handler *RpcHandler) HandlerRpcResponseCB(call *Call) {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -226,7 +237,7 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("Handler Rpc ", request.RpcRequestData.GetServiceMethod(), " Core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
rpcErr := RpcError("call error : core dumps") rpcErr := RpcError("call error : core dumps")
if request.requestHandle != nil { if request.requestHandle != nil {
request.requestHandle(nil, rpcErr) request.requestHandle(nil, rpcErr)
@@ -239,12 +250,12 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
if rawRpcId > 0 { if rawRpcId > 0 {
v, ok := handler.mapRawFunctions[rawRpcId] v, ok := handler.mapRawFunctions[rawRpcId]
if ok == false { if ok == false {
log.SError("RpcHandler cannot find request rpc id", rawRpcId) log.Error("RpcHandler cannot find request rpc id",log.Uint32("rawRpcId",rawRpcId))
return return
} }
rawData,ok := request.inParam.([]byte) rawData,ok := request.inParam.([]byte)
if ok == false { if ok == false {
log.SError("RpcHandler " + handler.rpcHandler.GetName()," cannot convert in param to []byte", rawRpcId) log.Error("RpcHandler cannot convert",log.String("RpcHandlerName",handler.rpcHandler.GetName()),log.Uint32("rawRpcId",rawRpcId))
return return
} }
@@ -256,7 +267,7 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
v, ok := handler.mapFunctions[request.RpcRequestData.GetServiceMethod()] v, ok := handler.mapFunctions[request.RpcRequestData.GetServiceMethod()]
if ok == false { if ok == false {
err := "RpcHandler " + handler.rpcHandler.GetName() + "cannot find " + request.RpcRequestData.GetServiceMethod() err := "RpcHandler " + handler.rpcHandler.GetName() + "cannot find " + request.RpcRequestData.GetServiceMethod()
log.SError(err) log.Error("HandlerRpcRequest cannot find serviceMethod",log.String("RpcHandlerName",handler.rpcHandler.GetName()),log.String("serviceMethod",request.RpcRequestData.GetServiceMethod()))
if request.requestHandle != nil { if request.requestHandle != nil {
request.requestHandle(nil, RpcError(err)) request.requestHandle(nil, RpcError(err))
} }
@@ -287,7 +298,7 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
paramList = append(paramList, oParam) //输出参数 paramList = append(paramList, oParam) //输出参数
} else if request.requestHandle != nil && v.hasResponder == false { //调用方有返回值,但被调用函数没有返回参数 } else if request.requestHandle != nil && v.hasResponder == false { //调用方有返回值,但被调用函数没有返回参数
rErr := "Call Rpc " + request.RpcRequestData.GetServiceMethod() + " without return parameter!" rErr := "Call Rpc " + request.RpcRequestData.GetServiceMethod() + " without return parameter!"
log.SError(rErr) log.Error("call serviceMethod without return parameter",log.String("serviceMethod",request.RpcRequestData.GetServiceMethod()))
request.requestHandle(nil, RpcError(rErr)) request.requestHandle(nil, RpcError(rErr))
return return
} }
@@ -309,7 +320,7 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
v, ok := handler.mapFunctions[ServiceMethod] v, ok := handler.mapFunctions[ServiceMethod]
if ok == false { if ok == false {
err = errors.New("RpcHandler " + handler.rpcHandler.GetName() + " cannot find" + ServiceMethod) err = errors.New("RpcHandler " + handler.rpcHandler.GetName() + " cannot find" + ServiceMethod)
log.SError(err.Error()) log.Error("CallMethod cannot find serviceMethod",log.String("rpcHandlerName",handler.rpcHandler.GetName()),log.String("serviceMethod",ServiceMethod))
return err return err
} }
@@ -323,7 +334,8 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
pCall.callback = &callBack pCall.callback = &callBack
pCall.Seq = client.generateSeq() pCall.Seq = client.generateSeq()
callSeq = pCall.Seq callSeq = pCall.Seq
pCall.TimeOut = DefaultRpcTimeout
pCall.ServiceMethod = ServiceMethod
client.AddPending(pCall) client.AddPending(pCall)
//有返回值时 //有返回值时
@@ -332,7 +344,7 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
hander :=func(Returns interface{}, Err RpcError) { hander :=func(Returns interface{}, Err RpcError) {
rpcCall := client.RemovePending(callSeq) rpcCall := client.RemovePending(callSeq)
if rpcCall == nil { if rpcCall == nil {
log.SError("cannot find call seq ",callSeq) log.Error("cannot find call seq",log.Uint64("seq",callSeq))
return return
} }
@@ -416,24 +428,24 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
func (handler *RpcHandler) goRpc(processor IRpcProcessor, bCast bool, nodeId int, serviceMethod string, args interface{}) error { func (handler *RpcHandler) goRpc(processor IRpcProcessor, bCast bool, nodeId int, serviceMethod string, args interface{}) error {
var pClientList [maxClusterNode]*Client var pClientList [maxClusterNode]*Client
err, count := handler.funcRpcClient(nodeId, serviceMethod, pClientList[:]) err, count := handler.funcRpcClient(nodeId, serviceMethod,false, pClientList[:])
if count == 0 { if count == 0 {
if err != nil { if err != nil {
log.SError("Call ", serviceMethod, " is error:", err.Error()) log.Error("call serviceMethod is failed",log.String("serviceMethod",serviceMethod),log.ErrorAttr("error",err))
} else { } else {
log.SError("Can not find ", serviceMethod) log.Error("cannot find serviceMethod",log.String("serviceMethod",serviceMethod))
} }
return err return err
} }
if count > 1 && bCast == false { if count > 1 && bCast == false {
log.SError("Cannot call %s more then 1 node!", serviceMethod) log.Error("cannot call serviceMethod more then 1 node",log.String("serviceMethod",serviceMethod))
return errors.New("cannot call more then 1 node") return errors.New("cannot call more then 1 node")
} }
//2.rpcClient调用 //2.rpcClient调用
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
pCall := pClientList[i].Go(handler.rpcHandler,true, serviceMethod, args, nil) pCall := pClientList[i].Go(DefaultRpcTimeout,handler.rpcHandler,true, serviceMethod, args, nil)
if pCall.Err != nil { if pCall.Err != nil {
err = pCall.Err err = pCall.Err
} }
@@ -444,23 +456,23 @@ func (handler *RpcHandler) goRpc(processor IRpcProcessor, bCast bool, nodeId int
return err return err
} }
func (handler *RpcHandler) callRpc(nodeId int, serviceMethod string, args interface{}, reply interface{}) error { func (handler *RpcHandler) callRpc(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, reply interface{}) error {
var pClientList [maxClusterNode]*Client var pClientList [maxClusterNode]*Client
err, count := handler.funcRpcClient(nodeId, serviceMethod, pClientList[:]) err, count := handler.funcRpcClient(nodeId, serviceMethod,false, pClientList[:])
if err != nil { if err != nil {
log.SError("Call serviceMethod is error:", err.Error()) log.Error("Call serviceMethod is failed",log.ErrorAttr("error",err))
return err return err
} else if count <= 0 { } else if count <= 0 {
err = errors.New("Call serviceMethod is error:cannot find " + serviceMethod) err = errors.New("Call serviceMethod is error:cannot find " + serviceMethod)
log.SError(err.Error()) log.Error("cannot find serviceMethod",log.String("serviceMethod",serviceMethod))
return err return err
} else if count > 1 { } else if count > 1 {
log.SError("Cannot call more then 1 node!") log.Error("Cannot call more then 1 node!",log.String("serviceMethod",serviceMethod))
return errors.New("cannot call more then 1 node") return errors.New("cannot call more then 1 node")
} }
pClient := pClientList[0] pClient := pClientList[0]
pCall := pClient.Go(handler.rpcHandler,false, serviceMethod, args, reply) pCall := pClient.Go(timeout,handler.rpcHandler,false, serviceMethod, args, reply)
err = pCall.Done().Err err = pCall.Done().Err
pClient.RemovePending(pCall.Seq) pClient.RemovePending(pCall.Seq)
@@ -468,29 +480,29 @@ func (handler *RpcHandler) callRpc(nodeId int, serviceMethod string, args interf
return err return err
} }
func (handler *RpcHandler) asyncCallRpc(nodeId int, serviceMethod string, args interface{}, callback interface{}) error { func (handler *RpcHandler) asyncCallRpc(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, callback interface{}) (CancelRpc,error) {
fVal := reflect.ValueOf(callback) fVal := reflect.ValueOf(callback)
if fVal.Kind() != reflect.Func { if fVal.Kind() != reflect.Func {
err := errors.New("call " + serviceMethod + " input callback param is error!") err := errors.New("call " + serviceMethod + " input callback param is error!")
log.SError(err.Error()) log.Error("input callback param is error",log.String("serviceMethod",serviceMethod))
return err return emptyCancelRpc,err
} }
if fVal.Type().NumIn() != 2 { if fVal.Type().NumIn() != 2 {
err := errors.New("call " + serviceMethod + " callback param function is error!") err := errors.New("call " + serviceMethod + " callback param function is error!")
log.SError(err.Error()) log.Error("callback param function is error",log.String("serviceMethod",serviceMethod))
return err return emptyCancelRpc,err
} }
if fVal.Type().In(0).Kind() != reflect.Ptr || fVal.Type().In(1).String() != "error" { if fVal.Type().In(0).Kind() != reflect.Ptr || fVal.Type().In(1).String() != "error" {
err := errors.New("call " + serviceMethod + " callback param function is error!") err := errors.New("call " + serviceMethod + " callback param function is error!")
log.SError(err.Error()) log.Error("callback param function is error",log.String("serviceMethod",serviceMethod))
return err return emptyCancelRpc,err
} }
reply := reflect.New(fVal.Type().In(0).Elem()).Interface() reply := reflect.New(fVal.Type().In(0).Elem()).Interface()
var pClientList [2]*Client var pClientList [2]*Client
err, count := handler.funcRpcClient(nodeId, serviceMethod, pClientList[:]) err, count := handler.funcRpcClient(nodeId, serviceMethod,false, pClientList[:])
if count == 0 || err != nil { if count == 0 || err != nil {
if err == nil { if err == nil {
if nodeId > 0 { if nodeId > 0 {
@@ -500,24 +512,20 @@ func (handler *RpcHandler) asyncCallRpc(nodeId int, serviceMethod string, args i
} }
} }
fVal.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)}) fVal.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
log.SError("Call serviceMethod is error:", err.Error()) log.Error("cannot find serviceMethod from node",log.String("serviceMethod",serviceMethod),log.Int("nodeId",nodeId))
return nil return emptyCancelRpc,nil
} }
if count > 1 { if count > 1 {
err := errors.New("cannot call more then 1 node") err := errors.New("cannot call more then 1 node")
fVal.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)}) fVal.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
log.SError(err.Error()) log.Error("cannot call more then 1 node",log.String("serviceMethod",serviceMethod))
return nil return emptyCancelRpc,nil
} }
//2.rpcClient调用 //2.rpcClient调用
//如果调用本结点服务 //如果调用本结点服务
pClient := pClientList[0] return pClientList[0].AsyncCall(timeout,handler.rpcHandler, serviceMethod, fVal, args, reply,false)
pClient.AsyncCall(handler.rpcHandler, serviceMethod, fVal, args, reply)
return nil
} }
func (handler *RpcHandler) GetName() string { func (handler *RpcHandler) GetName() string {
@@ -528,12 +536,29 @@ func (handler *RpcHandler) IsSingleCoroutine() bool {
return handler.rpcHandler.IsSingleCoroutine() return handler.rpcHandler.IsSingleCoroutine()
} }
func (handler *RpcHandler) CallWithTimeout(timeout time.Duration,serviceMethod string, args interface{}, reply interface{}) error {
return handler.callRpc(timeout,0, serviceMethod, args, reply)
}
func (handler *RpcHandler) CallNodeWithTimeout(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, reply interface{}) error{
return handler.callRpc(timeout,nodeId, serviceMethod, args, reply)
}
func (handler *RpcHandler) AsyncCallWithTimeout(timeout time.Duration,serviceMethod string, args interface{}, callback interface{}) (CancelRpc,error){
return handler.asyncCallRpc(timeout,0, serviceMethod, args, callback)
}
func (handler *RpcHandler) AsyncCallNodeWithTimeout(timeout time.Duration,nodeId int, serviceMethod string, args interface{}, callback interface{}) (CancelRpc,error){
return handler.asyncCallRpc(timeout,nodeId, serviceMethod, args, callback)
}
func (handler *RpcHandler) AsyncCall(serviceMethod string, args interface{}, callback interface{}) error { func (handler *RpcHandler) AsyncCall(serviceMethod string, args interface{}, callback interface{}) error {
return handler.asyncCallRpc(0, serviceMethod, args, callback) _,err := handler.asyncCallRpc(DefaultRpcTimeout,0, serviceMethod, args, callback)
return err
} }
func (handler *RpcHandler) Call(serviceMethod string, args interface{}, reply interface{}) error { func (handler *RpcHandler) Call(serviceMethod string, args interface{}, reply interface{}) error {
return handler.callRpc(0, serviceMethod, args, reply) return handler.callRpc(DefaultRpcTimeout,0, serviceMethod, args, reply)
} }
func (handler *RpcHandler) Go(serviceMethod string, args interface{}) error { func (handler *RpcHandler) Go(serviceMethod string, args interface{}) error {
@@ -541,11 +566,13 @@ func (handler *RpcHandler) Go(serviceMethod string, args interface{}) error {
} }
func (handler *RpcHandler) AsyncCallNode(nodeId int, serviceMethod string, args interface{}, callback interface{}) error { func (handler *RpcHandler) AsyncCallNode(nodeId int, serviceMethod string, args interface{}, callback interface{}) error {
return handler.asyncCallRpc(nodeId, serviceMethod, args, callback) _,err:= handler.asyncCallRpc(DefaultRpcTimeout,nodeId, serviceMethod, args, callback)
return err
} }
func (handler *RpcHandler) CallNode(nodeId int, serviceMethod string, args interface{}, reply interface{}) error { func (handler *RpcHandler) CallNode(nodeId int, serviceMethod string, args interface{}, reply interface{}) error {
return handler.callRpc(nodeId, serviceMethod, args, reply) return handler.callRpc(DefaultRpcTimeout,nodeId, serviceMethod, args, reply)
} }
func (handler *RpcHandler) GoNode(nodeId int, serviceMethod string, args interface{}) error { func (handler *RpcHandler) GoNode(nodeId int, serviceMethod string, args interface{}) error {
@@ -558,14 +585,14 @@ func (handler *RpcHandler) CastGo(serviceMethod string, args interface{}) error
func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType, nodeId int, rpcMethodId uint32, serviceName string, rawArgs []byte) error { func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType, nodeId int, rpcMethodId uint32, serviceName string, rawArgs []byte) error {
processor := GetProcessor(uint8(rpcProcessorType)) processor := GetProcessor(uint8(rpcProcessorType))
err, count := handler.funcRpcClient(nodeId, serviceName, handler.pClientList) err, count := handler.funcRpcClient(nodeId, serviceName,false, handler.pClientList)
if count == 0 || err != nil { if count == 0 || err != nil {
log.SError("Call serviceMethod is error:", err.Error()) log.Error("call serviceMethod is failed",log.ErrorAttr("error",err))
return err return err
} }
if count > 1 { if count > 1 {
err := errors.New("cannot call more then 1 node") err := errors.New("cannot call more then 1 node")
log.SError(err.Error()) log.Error("cannot call more then 1 node",log.String("serviceName",serviceName))
return err return err
} }
@@ -573,7 +600,7 @@ func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType, nodeId i
//如果调用本结点服务 //如果调用本结点服务
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
//跨node调用 //跨node调用
pCall := handler.pClientList[i].RawGo(handler.rpcHandler,processor, true, rpcMethodId, serviceName, rawArgs, nil) pCall := handler.pClientList[i].RawGo(DefaultRpcTimeout,handler.rpcHandler,processor, true, rpcMethodId, serviceName, rawArgs, nil)
if pCall.Err != nil { if pCall.Err != nil {
err = pCall.Err err = pCall.Err
} }

89
rpc/rpctimer.go Normal file
View File

@@ -0,0 +1,89 @@
package rpc
import (
"container/heap"
"time"
)
type CallTimer struct {
SeqId uint64
FireTime int64
}
type CallTimerHeap struct {
callTimer []CallTimer
mapSeqIndex map[uint64]int
}
func (h *CallTimerHeap) Init() {
h.mapSeqIndex = make(map[uint64]int, 4096)
h.callTimer = make([]CallTimer, 0, 4096)
}
func (h *CallTimerHeap) Len() int {
return len(h.callTimer)
}
func (h *CallTimerHeap) Less(i, j int) bool {
return h.callTimer[i].FireTime < h.callTimer[j].FireTime
}
func (h *CallTimerHeap) Swap(i, j int) {
h.callTimer[i], h.callTimer[j] = h.callTimer[j], h.callTimer[i]
h.mapSeqIndex[h.callTimer[i].SeqId] = i
h.mapSeqIndex[h.callTimer[j].SeqId] = j
}
func (h *CallTimerHeap) Push(t any) {
callTimer := t.(CallTimer)
h.mapSeqIndex[callTimer.SeqId] = len(h.callTimer)
h.callTimer = append(h.callTimer, callTimer)
}
func (h *CallTimerHeap) Pop() any {
l := len(h.callTimer)
seqId := h.callTimer[l-1].SeqId
h.callTimer = h.callTimer[:l-1]
delete(h.mapSeqIndex, seqId)
return seqId
}
func (h *CallTimerHeap) Cancel(seq uint64) bool {
index, ok := h.mapSeqIndex[seq]
if ok == false {
return false
}
heap.Remove(h, index)
return true
}
func (h *CallTimerHeap) AddTimer(seqId uint64,d time.Duration){
heap.Push(h, CallTimer{
SeqId: seqId,
FireTime: time.Now().Add(d).UnixNano(),
})
}
func (h *CallTimerHeap) PopTimeout() uint64 {
if h.Len() == 0 {
return 0
}
nextFireTime := h.callTimer[0].FireTime
if nextFireTime > time.Now().UnixNano() {
return 0
}
return heap.Pop(h).(uint64)
}
func (h *CallTimerHeap) PopFirst() uint64 {
if h.Len() == 0 {
return 0
}
return heap.Pop(h).(uint64)
}

View File

@@ -10,16 +10,17 @@ import (
"reflect" "reflect"
"strings" "strings"
"time" "time"
"runtime"
) )
type RpcProcessorType uint8 type RpcProcessorType uint8
const ( const (
RpcProcessorJson RpcProcessorType = 0 RpcProcessorJson RpcProcessorType = 0
RpcProcessorGoGoPB RpcProcessorType = 1 RpcProcessorPB RpcProcessorType = 1
) )
var arrayProcessor = []IRpcProcessor{&JsonProcessor{}, &GoGoPBProcessor{}} var arrayProcessor = []IRpcProcessor{&JsonProcessor{}, &PBProcessor{}}
var arrayProcessorLen uint8 = 2 var arrayProcessorLen uint8 = 2
var LittleEndian bool var LittleEndian bool
@@ -27,6 +28,8 @@ type Server struct {
functions map[interface{}]interface{} functions map[interface{}]interface{}
rpcHandleFinder RpcHandleFinder rpcHandleFinder RpcHandleFinder
rpcServer *network.TCPServer rpcServer *network.TCPServer
compressBytesLen int
} }
type RpcAgent struct { type RpcAgent struct {
@@ -64,14 +67,15 @@ func (server *Server) Init(rpcHandleFinder RpcHandleFinder) {
const Default_ReadWriteDeadline = 15*time.Second const Default_ReadWriteDeadline = 15*time.Second
func (server *Server) Start(listenAddr string, maxRpcParamLen uint32) { func (server *Server) Start(listenAddr string, maxRpcParamLen uint32,compressBytesLen int) {
splitAddr := strings.Split(listenAddr, ":") splitAddr := strings.Split(listenAddr, ":")
if len(splitAddr) != 2 { if len(splitAddr) != 2 {
log.SFatal("listen addr is error :", listenAddr) log.Fatal("listen addr is failed", log.String("listenAddr",listenAddr))
} }
server.rpcServer.Addr = ":" + splitAddr[1] server.rpcServer.Addr = ":" + splitAddr[1]
server.rpcServer.MinMsgLen = 2 server.rpcServer.MinMsgLen = 2
server.compressBytesLen = compressBytesLen
if maxRpcParamLen > 0 { if maxRpcParamLen > 0 {
server.rpcServer.MaxMsgLen = maxRpcParamLen server.rpcServer.MaxMsgLen = maxRpcParamLen
} else { } else {
@@ -108,38 +112,84 @@ func (agent *RpcAgent) WriteResponse(processor IRpcProcessor, serviceMethod stri
defer processor.ReleaseRpcResponse(rpcResponse.RpcResponseData) defer processor.ReleaseRpcResponse(rpcResponse.RpcResponseData)
if errM != nil { if errM != nil {
log.SError("service method ", serviceMethod, " Marshal error:", errM.Error()) log.Error("mashal RpcResponseData failed",log.String("serviceMethod",serviceMethod),log.ErrorAttr("error",errM))
return return
} }
errM = agent.conn.WriteMsg([]byte{uint8(processor.GetProcessorType())}, bytes) var compressBuff[]byte
bCompress := uint8(0)
if agent.rpcServer.compressBytesLen >0 && len(bytes) >= agent.rpcServer.compressBytesLen {
var cErr error
compressBuff,cErr = compressor.CompressBlock(bytes)
if cErr != nil {
log.Error("CompressBlock failed",log.String("serviceMethod",serviceMethod),log.ErrorAttr("error",cErr))
return
}
if len(compressBuff) < len(bytes) {
bytes = compressBuff
bCompress = 1<<7
}
}
errM = agent.conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
if cap(compressBuff) >0 {
compressor.CompressBufferCollection(compressBuff)
}
if errM != nil { if errM != nil {
log.SError("Rpc ", serviceMethod, " return is error:", errM.Error()) log.Error("WriteMsg error,Rpc return is fail",log.String("serviceMethod",serviceMethod),log.ErrorAttr("error",errM))
} }
} }
func (agent *RpcAgent) Run() { func (agent *RpcAgent) Run() {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 4096)
l := runtime.Stack(buf, false)
errString := fmt.Sprint(r)
log.Dump(string(buf[:l]),log.String("error",errString))
}
}()
for { for {
data, err := agent.conn.ReadMsg() data, err := agent.conn.ReadMsg()
if err != nil { if err != nil {
log.SError("remoteAddress:", agent.conn.RemoteAddr().String(), ",read message: ", err.Error()) log.Error("read message is error",log.String("remoteAddress",agent.conn.RemoteAddr().String()),log.ErrorAttr("error",err))
//will close tcpconn //will close tcpconn
break break
} }
processor := GetProcessor(data[0]) bCompress := (data[0]>>7) > 0
processor := GetProcessor(data[0]&0x7f)
if processor == nil { if processor == nil {
agent.conn.ReleaseReadMsg(data) agent.conn.ReleaseReadMsg(data)
log.SError("remote rpc ", agent.conn.RemoteAddr(), " cannot find processor:", data[0]) log.Warning("cannot find processor",log.String("RemoteAddr",agent.conn.RemoteAddr().String()))
return return
} }
//解析head //解析head
var compressBuff []byte
byteData := data[1:]
if bCompress == true {
var unCompressErr error
compressBuff,unCompressErr = compressor.UncompressBlock(byteData)
if unCompressErr!= nil {
agent.conn.ReleaseReadMsg(data)
log.Error("UncompressBlock failed",log.String("RemoteAddr",agent.conn.RemoteAddr().String()),log.ErrorAttr("error",unCompressErr))
return
}
byteData = compressBuff
}
req := MakeRpcRequest(processor, 0, 0, "", false, nil) req := MakeRpcRequest(processor, 0, 0, "", false, nil)
err = processor.Unmarshal(data[1:], req.RpcRequestData) err = processor.Unmarshal(byteData, req.RpcRequestData)
if cap(compressBuff) > 0 {
compressor.UnCompressBufferCollection(compressBuff)
}
agent.conn.ReleaseReadMsg(data) agent.conn.ReleaseReadMsg(data)
if err != nil { if err != nil {
log.SError("rpc Unmarshal request is error:", err.Error()) log.Error("Unmarshal failed",log.String("RemoteAddr",agent.conn.RemoteAddr().String()),log.ErrorAttr("error",err))
if req.RpcRequestData.GetSeq() > 0 { if req.RpcRequestData.GetSeq() > 0 {
rpcError := RpcError(err.Error()) rpcError := RpcError(err.Error())
if req.RpcRequestData.IsNoReply() == false { if req.RpcRequestData.IsNoReply() == false {
@@ -161,7 +211,7 @@ func (agent *RpcAgent) Run() {
agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError) agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError)
} }
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
log.SError("rpc request req.ServiceMethod is error") log.Error("rpc request req.ServiceMethod is error")
continue continue
} }
@@ -171,8 +221,7 @@ func (agent *RpcAgent) Run() {
if req.RpcRequestData.IsNoReply() == false { if req.RpcRequestData.IsNoReply() == false {
agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError) agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError)
} }
log.Error("serviceMethod not config",log.String("serviceMethod",req.RpcRequestData.GetServiceMethod()))
log.SError("service method ", req.RpcRequestData.GetServiceMethod(), " not config!")
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
continue continue
} }
@@ -187,12 +236,13 @@ func (agent *RpcAgent) Run() {
req.inParam, err = rpcHandler.UnmarshalInParam(req.rpcProcessor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetRpcMethodId(), req.RpcRequestData.GetInParam()) req.inParam, err = rpcHandler.UnmarshalInParam(req.rpcProcessor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetRpcMethodId(), req.RpcRequestData.GetInParam())
if err != nil { if err != nil {
rErr := "Call Rpc " + req.RpcRequestData.GetServiceMethod() + " Param error " + err.Error() rErr := "Call Rpc " + req.RpcRequestData.GetServiceMethod() + " Param error " + err.Error()
log.Error("call rpc param error",log.String("serviceMethod",req.RpcRequestData.GetServiceMethod()),log.ErrorAttr("error",err))
if req.requestHandle != nil { if req.requestHandle != nil {
req.requestHandle(nil, RpcError(rErr)) req.requestHandle(nil, RpcError(rErr))
} else { } else {
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
} }
log.SError(rErr)
continue continue
} }
@@ -241,23 +291,23 @@ func (server *Server) myselfRpcHandlerGo(client *Client,handlerName string, serv
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName) rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
if rpcHandler == nil { if rpcHandler == nil {
err := errors.New("service method " + serviceMethod + " not config!") err := errors.New("service method " + serviceMethod + " not config!")
log.SError(err.Error()) log.Error("service method not config",log.String("serviceMethod",serviceMethod))
return err return err
} }
return rpcHandler.CallMethod(client,serviceMethod, args,callBack, reply) return rpcHandler.CallMethod(client,serviceMethod, args,callBack, reply)
} }
func (server *Server) selfNodeRpcHandlerGo(timeout time.Duration,processor IRpcProcessor, client *Client, noReply bool, handlerName string, rpcMethodId uint32, serviceMethod string, args interface{}, reply interface{}, rawArgs []byte) *Call {
func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Client, noReply bool, handlerName string, rpcMethodId uint32, serviceMethod string, args interface{}, reply interface{}, rawArgs []byte) *Call {
pCall := MakeCall() pCall := MakeCall()
pCall.Seq = client.generateSeq() pCall.Seq = client.generateSeq()
pCall.TimeOut = timeout
pCall.ServiceMethod = serviceMethod
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName) rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
if rpcHandler == nil { if rpcHandler == nil {
err := errors.New("service method " + serviceMethod + " not config!") err := errors.New("service method " + serviceMethod + " not config!")
log.SError(err.Error()) log.Error("service method not config",log.String("serviceMethod",serviceMethod),log.ErrorAttr("error",err))
pCall.Seq = 0 pCall.Seq = 0
pCall.DoError(err) pCall.DoError(err)
@@ -274,7 +324,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
iParam,err = processor.Clone(args) iParam,err = processor.Clone(args)
if err != nil { if err != nil {
sErr := errors.New("RpcHandler " + handlerName + "."+serviceMethod+" deep copy inParam is error:" + err.Error()) sErr := errors.New("RpcHandler " + handlerName + "."+serviceMethod+" deep copy inParam is error:" + err.Error())
log.SError(sErr.Error()) log.Error("deep copy inParam is failed",log.String("handlerName",handlerName),log.String("serviceMethod",serviceMethod))
pCall.Seq = 0 pCall.Seq = 0
pCall.DoError(sErr) pCall.DoError(sErr)
@@ -289,7 +339,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
var err error var err error
req.inParam, err = rpcHandler.UnmarshalInParam(processor, serviceMethod, rpcMethodId, rawArgs) req.inParam, err = rpcHandler.UnmarshalInParam(processor, serviceMethod, rpcMethodId, rawArgs)
if err != nil { if err != nil {
log.SError(err.Error()) log.Error("unmarshalInParam is failed",log.String("serviceMethod",serviceMethod),log.Uint32("rpcMethodId",rpcMethodId),log.ErrorAttr("error",err))
pCall.Seq = 0 pCall.Seq = 0
pCall.DoError(err) pCall.DoError(err)
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
@@ -305,12 +355,12 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
byteReturns, err := req.rpcProcessor.Marshal(Returns) byteReturns, err := req.rpcProcessor.Marshal(Returns)
if err != nil { if err != nil {
Err = ConvertError(err) Err = ConvertError(err)
log.SError("returns data cannot be marshal,callSeq is ", callSeq," error is ",err.Error()) log.Error("returns data cannot be marshal",log.Uint64("seq",callSeq),log.ErrorAttr("error",err))
}else{ }else{
err = req.rpcProcessor.Unmarshal(byteReturns, reply) err = req.rpcProcessor.Unmarshal(byteReturns, reply)
if err != nil { if err != nil {
Err = ConvertError(err) Err = ConvertError(err)
log.SError("returns data cannot be Unmarshal,callSeq is ", callSeq," error is ",err.Error()) log.Error("returns data cannot be Unmarshal",log.Uint64("seq",callSeq),log.ErrorAttr("error",err))
} }
} }
} }
@@ -318,8 +368,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
v := client.RemovePending(callSeq) v := client.RemovePending(callSeq)
if v == nil { if v == nil {
log.SError("rpcClient cannot find seq ",callSeq, " in pending") log.Error("rpcClient cannot find seq",log.Uint64("seq",callSeq))
return return
} }
@@ -327,7 +376,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
v.Err = nil v.Err = nil
v.DoOK() v.DoOK()
} else { } else {
log.SError(Err.Error()) log.Error(Err.Error())
v.DoError(Err) v.DoError(Err)
} }
} }
@@ -335,7 +384,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
err := rpcHandler.PushRpcRequest(req) err := rpcHandler.PushRpcRequest(req)
if err != nil { if err != nil {
log.SError(err.Error()) log.Error(err.Error())
pCall.DoError(err) pCall.DoError(err)
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
} }
@@ -343,53 +392,57 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
return pCall return pCall
} }
func (server *Server) selfNodeRpcHandlerAsyncGo(client *Client, callerRpcHandler IRpcHandler, noReply bool, handlerName string, serviceMethod string, args interface{}, reply interface{}, callback reflect.Value) error { func (server *Server) selfNodeRpcHandlerAsyncGo(timeout time.Duration,client *Client, callerRpcHandler IRpcHandler, noReply bool, handlerName string, serviceMethod string, args interface{}, reply interface{}, callback reflect.Value,cancelable bool) (CancelRpc,error) {
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName) rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
if rpcHandler == nil { if rpcHandler == nil {
err := errors.New("service method " + serviceMethod + " not config!") err := errors.New("service method " + serviceMethod + " not config!")
log.SError(err.Error()) log.Error(err.Error())
return err return emptyCancelRpc,err
} }
_, processor := GetProcessorType(args) _, processor := GetProcessorType(args)
iParam,err := processor.Clone(args) iParam,err := processor.Clone(args)
if err != nil { if err != nil {
errM := errors.New("RpcHandler " + handlerName + "."+serviceMethod+" deep copy inParam is error:" + err.Error()) errM := errors.New("RpcHandler " + handlerName + "."+serviceMethod+" deep copy inParam is error:" + err.Error())
log.SError(errM.Error()) log.Error(errM.Error())
return errM return emptyCancelRpc,errM
} }
req := MakeRpcRequest(processor, 0, 0, serviceMethod, noReply, nil) req := MakeRpcRequest(processor, 0, 0, serviceMethod, noReply, nil)
req.inParam = iParam req.inParam = iParam
req.localReply = reply req.localReply = reply
cancelRpc := emptyCancelRpc
var callSeq uint64
if noReply == false { if noReply == false {
callSeq := client.generateSeq() callSeq = client.generateSeq()
pCall := MakeCall() pCall := MakeCall()
pCall.Seq = callSeq pCall.Seq = callSeq
pCall.rpcHandler = callerRpcHandler pCall.rpcHandler = callerRpcHandler
pCall.callback = &callback pCall.callback = &callback
pCall.Reply = reply pCall.Reply = reply
pCall.ServiceMethod = serviceMethod pCall.ServiceMethod = serviceMethod
pCall.TimeOut = timeout
client.AddPending(pCall) client.AddPending(pCall)
rpcCancel := RpcCancel{CallSeq: callSeq,Cli: client}
cancelRpc = rpcCancel.CancelRpc
req.requestHandle = func(Returns interface{}, Err RpcError) { req.requestHandle = func(Returns interface{}, Err RpcError) {
v := client.RemovePending(callSeq) v := client.RemovePending(callSeq)
if v == nil { if v == nil {
log.SError("rpcClient cannot find seq ", pCall.Seq, " in pending")
//ReleaseCall(pCall)
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
return return
} }
if len(Err) == 0 { if len(Err) == 0 {
pCall.Err = nil v.Err = nil
} else { } else {
pCall.Err = Err v.Err = Err
} }
if Returns != nil { if Returns != nil {
pCall.Reply = Returns v.Reply = Returns
} }
pCall.rpcHandler.PushRpcResponse(pCall) v.rpcHandler.PushRpcResponse(v)
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
} }
} }
@@ -397,8 +450,11 @@ func (server *Server) selfNodeRpcHandlerAsyncGo(client *Client, callerRpcHandler
err = rpcHandler.PushRpcRequest(req) err = rpcHandler.PushRpcRequest(req)
if err != nil { if err != nil {
ReleaseRpcRequest(req) ReleaseRpcRequest(req)
return err if callSeq > 0 {
client.RemovePending(callSeq)
}
return emptyCancelRpc,err
} }
return nil return cancelRpc,nil
} }

View File

@@ -117,7 +117,7 @@ func (m *Module) AddModule(module IModule) (uint32, error) {
m.child[module.GetModuleId()] = module m.child[module.GetModuleId()] = module
m.ancestor.getBaseModule().(*Module).descendants[module.GetModuleId()] = module m.ancestor.getBaseModule().(*Module).descendants[module.GetModuleId()] = module
log.SDebug("Add module ", module.GetModuleName(), " completed") log.Debug("Add module "+module.GetModuleName()+ " completed")
return module.GetModuleId(), nil return module.GetModuleId(), nil
} }
@@ -131,7 +131,7 @@ func (m *Module) ReleaseModule(moduleId uint32) {
pModule.self.OnRelease() pModule.self.OnRelease()
pModule.GetEventHandler().Destroy() pModule.GetEventHandler().Destroy()
log.SDebug("Release module ", pModule.GetModuleName()) log.Debug("Release module "+ pModule.GetModuleName())
for pTimer := range pModule.mapActiveTimer { for pTimer := range pModule.mapActiveTimer {
pTimer.Cancel() pTimer.Cancel()
} }
@@ -278,18 +278,18 @@ func (m *Module) SafeNewTicker(tickerId *uint64, d time.Duration, AdditionData i
func (m *Module) CancelTimerId(timerId *uint64) bool { func (m *Module) CancelTimerId(timerId *uint64) bool {
if timerId==nil || *timerId == 0 { if timerId==nil || *timerId == 0 {
log.SWarning("timerId is invalid") log.Warning("timerId is invalid")
return false return false
} }
if m.mapActiveIdTimer == nil { if m.mapActiveIdTimer == nil {
log.SError("mapActiveIdTimer is nil") log.Error("mapActiveIdTimer is nil")
return false return false
} }
t, ok := m.mapActiveIdTimer[*timerId] t, ok := m.mapActiveIdTimer[*timerId]
if ok == false { if ok == false {
log.SStack("cannot find timer id ", timerId) log.Stack("cannot find timer id ", log.Uint64("timerId",*timerId))
return false return false
} }

View File

@@ -28,6 +28,7 @@ type IService interface {
OnSetup(iService IService) OnSetup(iService IService)
OnInit() error OnInit() error
OnStart() OnStart()
OnRetire()
OnRelease() OnRelease()
SetName(serviceName string) SetName(serviceName string)
@@ -40,6 +41,9 @@ type IService interface {
SetEventChannelNum(num int) SetEventChannelNum(num int)
OpenProfiler() OpenProfiler()
SetRetire() //设置服务退休状态
IsRetire() bool //服务是否退休
} }
type Service struct { type Service struct {
@@ -51,6 +55,7 @@ type Service struct {
serviceCfg interface{} serviceCfg interface{}
goroutineNum int32 goroutineNum int32
startStatus bool startStatus bool
retire int32
eventProcessor event.IEventProcessor eventProcessor event.IEventProcessor
profiler *profiler.Profiler //性能分析器 profiler *profiler.Profiler //性能分析器
nodeEventLister rpc.INodeListener nodeEventLister rpc.INodeListener
@@ -93,10 +98,23 @@ func (s *Service) OnSetup(iService IService){
func (s *Service) OpenProfiler() { func (s *Service) OpenProfiler() {
s.profiler = profiler.RegProfiler(s.GetName()) s.profiler = profiler.RegProfiler(s.GetName())
if s.profiler==nil { if s.profiler==nil {
log.SFatal("rofiler.RegProfiler ",s.GetName()," fail.") log.Fatal("rofiler.RegProfiler "+s.GetName()+" fail.")
} }
} }
func (s *Service) IsRetire() bool{
return atomic.LoadInt32(&s.retire) != 0
}
func (s *Service) SetRetire(){
atomic.StoreInt32(&s.retire,1)
ev := event.NewEvent()
ev.Type = event.Sys_Event_Retire
s.pushEvent(ev)
}
func (s *Service) Init(iService IService,getClientFun rpc.FuncRpcClient,getServerFun rpc.FuncRpcServer,serviceCfg interface{}) { func (s *Service) Init(iService IService,getClientFun rpc.FuncRpcClient,getServerFun rpc.FuncRpcServer,serviceCfg interface{}) {
s.closeSig = make(chan struct{}) s.closeSig = make(chan struct{})
s.dispatcher =timer.NewDispatcher(timerDispatcherLen) s.dispatcher =timer.NewDispatcher(timerDispatcherLen)
@@ -128,7 +146,7 @@ func (s *Service) Start() {
s.wg.Add(1) s.wg.Add(1)
waitRun.Add(1) waitRun.Add(1)
go func(){ go func(){
log.SRelease(s.GetName()," service is running",) log.Info(s.GetName()+" service is running",)
waitRun.Done() waitRun.Done()
s.Run() s.Run()
}() }()
@@ -155,15 +173,18 @@ func (s *Service) Run() {
concurrent.DoCallback(cb) concurrent.DoCallback(cb)
case ev := <- s.chanEvent: case ev := <- s.chanEvent:
switch ev.GetEventType() { switch ev.GetEventType() {
case event.Sys_Event_Retire:
log.Info("service OnRetire",log.String("servceName",s.GetName()))
s.self.(IService).OnRetire()
case event.ServiceRpcRequestEvent: case event.ServiceRpcRequestEvent:
cEvent,ok := ev.(*event.Event) cEvent,ok := ev.(*event.Event)
if ok == false { if ok == false {
log.SError("Type event conversion error") log.Error("Type event conversion error")
break break
} }
rpcRequest,ok := cEvent.Data.(*rpc.RpcRequest) rpcRequest,ok := cEvent.Data.(*rpc.RpcRequest)
if ok == false { if ok == false {
log.SError("Type *rpc.RpcRequest conversion error") log.Error("Type *rpc.RpcRequest conversion error")
break break
} }
if s.profiler!=nil { if s.profiler!=nil {
@@ -179,12 +200,12 @@ func (s *Service) Run() {
case event.ServiceRpcResponseEvent: case event.ServiceRpcResponseEvent:
cEvent,ok := ev.(*event.Event) cEvent,ok := ev.(*event.Event)
if ok == false { if ok == false {
log.SError("Type event conversion error") log.Error("Type event conversion error")
break break
} }
rpcResponseCB,ok := cEvent.Data.(*rpc.Call) rpcResponseCB,ok := cEvent.Data.(*rpc.Call)
if ok == false { if ok == false {
log.SError("Type *rpc.Call conversion error") log.Error("Type *rpc.Call conversion error")
break break
} }
if s.profiler!=nil { if s.profiler!=nil {
@@ -242,7 +263,7 @@ func (s *Service) Release(){
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[",errString,"]\n",string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -257,10 +278,10 @@ func (s *Service) OnInit() error {
} }
func (s *Service) Stop(){ func (s *Service) Stop(){
log.SRelease("stop ",s.GetName()," service ") log.Info("stop "+s.GetName()+" service ")
close(s.closeSig) close(s.closeSig)
s.wg.Wait() s.wg.Wait()
log.SRelease(s.GetName()," service has been stopped") log.Info(s.GetName()+" service has been stopped")
} }
func (s *Service) GetServiceCfg()interface{}{ func (s *Service) GetServiceCfg()interface{}{
@@ -304,7 +325,7 @@ func (s *Service) OnDiscoverServiceEvent(ev event.IEvent){
if event.IsDiscovery { if event.IsDiscovery {
s.discoveryServiceLister.OnDiscoveryService(event.NodeId,event.ServiceName) s.discoveryServiceLister.OnDiscoveryService(event.NodeId,event.ServiceName)
}else{ }else{
s.discoveryServiceLister.OnUnDiscoveryService(event.NodeId,event.ServiceName) s.discoveryServiceLister.OnUnDiscoveryService(event.NodeId)
} }
} }
@@ -353,7 +374,7 @@ func (s *Service) PushEvent(ev event.IEvent) error{
func (s *Service) pushEvent(ev event.IEvent) error{ func (s *Service) pushEvent(ev event.IEvent) error{
if len(s.chanEvent) >= maxServiceEventChannelNum { if len(s.chanEvent) >= maxServiceEventChannelNum {
err := errors.New("The event channel in the service is full") err := errors.New("The event channel in the service is full")
log.SError(err.Error()) log.Error(err.Error())
return err return err
} }
@@ -380,10 +401,13 @@ func (s *Service) SetEventChannelNum(num int){
func (s *Service) SetGoRoutineNum(goroutineNum int32) bool { func (s *Service) SetGoRoutineNum(goroutineNum int32) bool {
//已经开始状态不允许修改协程数量,打开性能分析器不允许开多线程 //已经开始状态不允许修改协程数量,打开性能分析器不允许开多线程
if s.startStatus == true || s.profiler!=nil { if s.startStatus == true || s.profiler!=nil {
log.SError("open profiler mode is not allowed to set Multi-coroutine.") log.Error("open profiler mode is not allowed to set Multi-coroutine.")
return false return false
} }
s.goroutineNum = goroutineNum s.goroutineNum = goroutineNum
return true return true
} }
func (s *Service) OnRetire(){
}

View File

@@ -60,3 +60,9 @@ func StopAllService(){
setupServiceList[i].Stop() setupServiceList[i].Stop()
} }
} }
func NotifyAllServiceRetire(){
for i := len(setupServiceList) - 1; i >= 0; i-- {
setupServiceList[i].SetRetire()
}
}

View File

@@ -1,4 +1,4 @@
package mysqlmondule package mysqlmodule
import ( import (
"database/sql" "database/sql"

View File

@@ -1,4 +1,4 @@
package mysqlmondule package mysqlmodule
import ( import (
"testing" "testing"

View File

@@ -104,11 +104,11 @@ func (cs *CustomerSubscriber) UnSubscribe() {
func (cs *CustomerSubscriber) LoadLastIndex() { func (cs *CustomerSubscriber) LoadLastIndex() {
for { for {
if atomic.LoadInt32(&cs.isStop) != 0 { if atomic.LoadInt32(&cs.isStop) != 0 {
log.SRelease("topic ", cs.topic, " out of subscription") log.Info("topic ", cs.topic, " out of subscription")
break break
} }
log.SRelease("customer ", cs.customerId, " start load last index ") log.Info("customer ", cs.customerId, " start load last index ")
lastIndex, ret := cs.subscriber.dataPersist.LoadCustomerIndex(cs.topic, cs.customerId) lastIndex, ret := cs.subscriber.dataPersist.LoadCustomerIndex(cs.topic, cs.customerId)
if ret == true { if ret == true {
if lastIndex > 0 { if lastIndex > 0 {
@@ -116,18 +116,18 @@ func (cs *CustomerSubscriber) LoadLastIndex() {
} else { } else {
//否则直接使用客户端发回来的 //否则直接使用客户端发回来的
} }
log.SRelease("customer ", cs.customerId, " load finish,start index is ", cs.StartIndex) log.Info("customer ", cs.customerId, " load finish,start index is ", cs.StartIndex)
break break
} }
log.SRelease("customer ", cs.customerId, " load last index is fail...") log.Info("customer ", cs.customerId, " load last index is fail...")
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
} }
} }
func (cs *CustomerSubscriber) SubscribeRun() { func (cs *CustomerSubscriber) SubscribeRun() {
defer cs.subscriber.queueWait.Done() defer cs.subscriber.queueWait.Done()
log.SRelease("topic ", cs.topic, " start subscription") log.Info("topic ", cs.topic, " start subscription")
//加载之前的位置 //加载之前的位置
if cs.subscribeMethod == MethodLast { if cs.subscribeMethod == MethodLast {
@@ -136,7 +136,7 @@ func (cs *CustomerSubscriber) SubscribeRun() {
for { for {
if atomic.LoadInt32(&cs.isStop) != 0 { if atomic.LoadInt32(&cs.isStop) != 0 {
log.SRelease("topic ", cs.topic, " out of subscription") log.Info("topic ", cs.topic, " out of subscription")
break break
} }
@@ -146,14 +146,14 @@ func (cs *CustomerSubscriber) SubscribeRun() {
//todo 检测退出 //todo 检测退出
if cs.subscribe() == false { if cs.subscribe() == false {
log.SRelease("topic ", cs.topic, " out of subscription") log.Info("topic ", cs.topic, " out of subscription")
break break
} }
} }
//删除订阅关系 //删除订阅关系
cs.subscriber.removeCustomer(cs.customerId, cs) cs.subscriber.removeCustomer(cs.customerId, cs)
log.SRelease("topic ", cs.topic, " unsubscription") log.Info("topic ", cs.topic, " unsubscription")
} }
func (cs *CustomerSubscriber) subscribe() bool { func (cs *CustomerSubscriber) subscribe() bool {
@@ -213,7 +213,7 @@ func (cs *CustomerSubscriber) publishToCustomer(topicData []TopicData) bool {
} }
//推送数据 //推送数据
err := cs.CallNode(cs.fromNodeId, cs.callBackRpcMethod, &dbQueuePublishReq, &dbQueuePushRes) err := cs.CallNodeWithTimeout(4*time.Minute,cs.fromNodeId, cs.callBackRpcMethod, &dbQueuePublishReq, &dbQueuePushRes)
if err != nil { if err != nil {
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
continue continue

View File

@@ -63,7 +63,7 @@ func (ms *MessageQueueService) ReadCfg() error {
maxProcessTopicBacklogNum, ok := mapDBServiceCfg["MaxProcessTopicBacklogNum"] maxProcessTopicBacklogNum, ok := mapDBServiceCfg["MaxProcessTopicBacklogNum"]
if ok == false { if ok == false {
ms.maxProcessTopicBacklogNum = DefaultMaxTopicBacklogNum ms.maxProcessTopicBacklogNum = DefaultMaxTopicBacklogNum
log.SRelease("MaxProcessTopicBacklogNum config is set to the default value of ", maxProcessTopicBacklogNum) log.Info("MaxProcessTopicBacklogNum config is set to the default value of ", maxProcessTopicBacklogNum)
} else { } else {
ms.maxProcessTopicBacklogNum = int32(maxProcessTopicBacklogNum.(float64)) ms.maxProcessTopicBacklogNum = int32(maxProcessTopicBacklogNum.(float64))
} }
@@ -71,7 +71,7 @@ func (ms *MessageQueueService) ReadCfg() error {
memoryQueueLen, ok := mapDBServiceCfg["MemoryQueueLen"] memoryQueueLen, ok := mapDBServiceCfg["MemoryQueueLen"]
if ok == false { if ok == false {
ms.memoryQueueLen = DefaultMemoryQueueLen ms.memoryQueueLen = DefaultMemoryQueueLen
log.SRelease("MemoryQueueLen config is set to the default value of ", DefaultMemoryQueueLen) log.Info("MemoryQueueLen config is set to the default value of ", DefaultMemoryQueueLen)
} else { } else {
ms.memoryQueueLen = int32(memoryQueueLen.(float64)) ms.memoryQueueLen = int32(memoryQueueLen.(float64))
} }

View File

@@ -56,9 +56,9 @@ func (ss *Subscriber) TopicSubscribe(rpcHandler rpc.IRpcHandler, subScribeType r
} }
if ok == true { if ok == true {
log.SRelease("repeat subscription for customer ", customerId) log.Info("repeat subscription for customer ", customerId)
} else { } else {
log.SRelease("subscription for customer ", customerId) log.Info("subscription for customer ", customerId)
} }
} }

View File

@@ -93,7 +93,7 @@ func (tr *TopicRoom) Stop() {
func (tr *TopicRoom) topicRoomRun() { func (tr *TopicRoom) topicRoomRun() {
defer tr.queueWait.Done() defer tr.queueWait.Done()
log.SRelease("topic room ", tr.topic, " is running..") log.Info("topic room ", tr.topic, " is running..")
for { for {
if atomic.LoadInt32(&tr.isStop) != 0 { if atomic.LoadInt32(&tr.isStop) != 0 {
break break
@@ -145,5 +145,5 @@ func (tr *TopicRoom) topicRoomRun() {
} }
tr.customerLocker.Unlock() tr.customerLocker.Unlock()
log.SRelease("topic room ", tr.topic, " is stop") log.Info("topic room ", tr.topic, " is stop")
} }

View File

@@ -142,13 +142,13 @@ func (mp *MongoPersist) OnSetupRank(manual bool,rankSkip *RankSkip) error{
return nil return nil
} }
log.SRelease("start load rank ",rankSkip.GetRankName()," from mongodb.") log.Info("start load rank ",rankSkip.GetRankName()," from mongodb.")
err := mp.loadFromDB(rankSkip.GetRankID(),rankSkip.GetRankName()) err := mp.loadFromDB(rankSkip.GetRankID(),rankSkip.GetRankName())
if err != nil { if err != nil {
log.SError("load from db is fail :%s",err.Error()) log.SError("load from db is fail :%s",err.Error())
return err return err
} }
log.SRelease("finish load rank ",rankSkip.GetRankName()," from mongodb.") log.Info("finish load rank ",rankSkip.GetRankName()," from mongodb.")
return nil return nil
} }
@@ -297,7 +297,7 @@ func (mp *MongoPersist) saveToDB(){
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError(" Core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()

View File

@@ -8,10 +8,11 @@ import (
"github.com/duanhf2012/origin/network/processor" "github.com/duanhf2012/origin/network/processor"
"github.com/duanhf2012/origin/node" "github.com/duanhf2012/origin/node"
"github.com/duanhf2012/origin/service" "github.com/duanhf2012/origin/service"
"sync/atomic" "github.com/duanhf2012/origin/util/bytespool"
"sync"
"time"
"runtime" "runtime"
"sync"
"sync/atomic"
"time"
) )
type TcpService struct { type TcpService struct {
@@ -52,18 +53,9 @@ type Client struct {
} }
func (tcpService *TcpService) genId() uint64 { func (tcpService *TcpService) genId() uint64 {
if node.GetNodeId()>MaxNodeId{
panic("nodeId exceeds the maximum!")
}
newSeed := atomic.AddUint32(&seed,1) % MaxSeed newSeed := atomic.AddUint32(&seed,1) % MaxSeed
nowTime := uint64(time.Now().Unix())%MaxTime nowTime := uint64(time.Now().Unix())%MaxTime
return (uint64(node.GetNodeId())<<50)|(nowTime<<19)|uint64(newSeed) return (uint64(node.GetNodeId()%MaxNodeId)<<50)|(nowTime<<19)|uint64(newSeed)
}
func GetNodeId(agentId uint64) int {
return int(agentId>>50)
} }
func (tcpService *TcpService) OnInit() error{ func (tcpService *TcpService) OnInit() error{
@@ -170,7 +162,7 @@ func (slf *Client) Run() {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[",errString,"]\n",string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -183,7 +175,7 @@ func (slf *Client) Run() {
slf.tcpConn.SetReadDeadline(slf.tcpService.tcpServer.ReadDeadline) slf.tcpConn.SetReadDeadline(slf.tcpService.tcpServer.ReadDeadline)
bytes,err := slf.tcpConn.ReadMsg() bytes,err := slf.tcpConn.ReadMsg()
if err != nil { if err != nil {
log.SDebug("read client id ",slf.id," is error:",err.Error()) log.Debug("read client failed",log.ErrorAttr("error",err),log.Uint64("clientId",slf.id))
break break
} }
data,err:=slf.tcpService.process.Unmarshal(slf.id,bytes) data,err:=slf.tcpService.process.Unmarshal(slf.id,bytes)
@@ -277,14 +269,14 @@ func (tcpService *TcpService) GetConnNum() int {
return connNum return connNum
} }
func (server *TcpService) SetNetMempool(mempool network.INetMempool){ func (server *TcpService) SetNetMempool(mempool bytespool.IBytesMempool){
server.tcpServer.SetNetMempool(mempool) server.tcpServer.SetNetMempool(mempool)
} }
func (server *TcpService) GetNetMempool() network.INetMempool{ func (server *TcpService) GetNetMempool() bytespool.IBytesMempool {
return server.tcpServer.GetNetMempool() return server.tcpServer.GetNetMempool()
} }
func (server *TcpService) ReleaseNetMem(byteBuff []byte) { func (server *TcpService) ReleaseNetMem(byteBuff []byte) {
server.tcpServer.GetNetMempool().ReleaseByteSlice(byteBuff) server.tcpServer.GetNetMempool().ReleaseBytes(byteBuff)
} }

View File

@@ -1,12 +1,12 @@
package network package bytespool
import ( import (
"sync" "sync"
) )
type INetMempool interface { type IBytesMempool interface {
MakeByteSlice(size int) []byte MakeBytes(size int) []byte
ReleaseByteSlice(byteBuff []byte) bool ReleaseBytes(byteBuff []byte) bool
} }
type memAreaPool struct { type memAreaPool struct {
@@ -16,7 +16,7 @@ type memAreaPool struct {
pool []sync.Pool pool []sync.Pool
} }
var memAreaPoolList = [3]*memAreaPool{&memAreaPool{minAreaValue: 1, maxAreaValue: 4096, growthValue: 512}, &memAreaPool{minAreaValue: 4097, maxAreaValue: 40960, growthValue: 4096}, &memAreaPool{minAreaValue: 40961, maxAreaValue: 417792, growthValue: 16384}} var memAreaPoolList = [4]*memAreaPool{&memAreaPool{minAreaValue: 1, maxAreaValue: 4096, growthValue: 512}, &memAreaPool{minAreaValue: 4097, maxAreaValue: 40960, growthValue: 4096}, &memAreaPool{minAreaValue: 40961, maxAreaValue: 417792, growthValue: 16384}, &memAreaPool{minAreaValue: 417793, maxAreaValue: 1925120, growthValue: 65536}}
func init() { func init() {
for i := 0; i < len(memAreaPoolList); i++ { for i := 0; i < len(memAreaPoolList); i++ {
@@ -68,7 +68,7 @@ func (areaPool *memAreaPool) releaseByteSlice(byteBuff []byte) bool {
return true return true
} }
func (areaPool *memAreaPool) MakeByteSlice(size int) []byte { func (areaPool *memAreaPool) MakeBytes(size int) []byte {
for i := 0; i < len(memAreaPoolList); i++ { for i := 0; i < len(memAreaPoolList); i++ {
if size <= memAreaPoolList[i].maxAreaValue { if size <= memAreaPoolList[i].maxAreaValue {
return memAreaPoolList[i].makeByteSlice(size) return memAreaPoolList[i].makeByteSlice(size)
@@ -78,7 +78,7 @@ func (areaPool *memAreaPool) MakeByteSlice(size int) []byte {
return make([]byte, size) return make([]byte, size)
} }
func (areaPool *memAreaPool) ReleaseByteSlice(byteBuff []byte) bool { func (areaPool *memAreaPool) ReleaseBytes(byteBuff []byte) bool {
for i := 0; i < len(memAreaPoolList); i++ { for i := 0; i < len(memAreaPoolList); i++ {
if cap(byteBuff) <= memAreaPoolList[i].maxAreaValue { if cap(byteBuff) <= memAreaPoolList[i].maxAreaValue {
return memAreaPoolList[i].releaseByteSlice(byteBuff) return memAreaPoolList[i].releaseByteSlice(byteBuff)

View File

@@ -1,6 +1,8 @@
package math package math
import "github.com/duanhf2012/origin/log" import (
"github.com/duanhf2012/origin/log"
)
type NumberType interface { type NumberType interface {
int | int8 | int16 | int32 | int64 | float32 | float64 | uint | uint8 | uint16 | uint32 | uint64 int | int8 | int16 | int32 | int64 | float32 | float64 | uint | uint8 | uint16 | uint32 | uint64
@@ -38,41 +40,90 @@ func Abs[NumType SignedNumberType](Num NumType) NumType {
return Num return Num
} }
func AddSafe[NumType NumberType](number1 NumType, number2 NumType) (NumType, bool) {
func Add[NumType NumberType](number1 NumType, number2 NumType) NumType {
ret := number1 + number2 ret := number1 + number2
if number2> 0 && ret < number1 { if number2 > 0 && ret < number1 {
log.SStack("Calculation overflow , number1 is ",number1," number2 is ",number2) log.Stack("Calculation overflow", log.Any("number1", number1), log.Any("number2", number2))
}else if (number2<0 && ret > number1){ return ret, false
log.SStack("Calculation overflow , number1 is ",number1," number2 is ",number2) } else if number2 < 0 && ret > number1 {
log.Stack("Calculation overflow", log.Any("number1", number1), log.Any("number2", number2))
return ret, false
} }
return ret, true
}
func SubSafe[NumType NumberType](number1 NumType, number2 NumType) (NumType, bool) {
ret := number1 - number2
if number2 > 0 && ret > number1 {
log.Stack("Calculation overflow", log.Any("number1", number1), log.Any("number2", number2))
return ret, false
} else if number2 < 0 && ret < number1 {
log.Stack("Calculation overflow", log.Any("number1", number1), log.Any("number2", number2))
return ret, false
}
return ret, true
}
func MulSafe[NumType NumberType](number1 NumType, number2 NumType) (NumType, bool) {
ret := number1 * number2
if number1 == 0 || number2 == 0 {
return ret, true
}
if ret/number2 == number1 {
return ret, true
}
log.Stack("Calculation overflow", log.Any("number1", number1), log.Any("number2", number2))
return ret, true
}
func Add[NumType NumberType](number1 NumType, number2 NumType) NumType {
ret, _ := AddSafe(number1, number2)
return ret return ret
} }
func Sub[NumType NumberType](number1 NumType, number2 NumType) NumType { func Sub[NumType NumberType](number1 NumType, number2 NumType) NumType {
ret := number1 - number2 ret, _ := SubSafe(number1, number2)
if number2> 0 && ret > number1 {
log.SStack("Calculation overflow , number1 is ",number1," number2 is ",number2)
}else if (number2<0 && ret < number1){
log.SStack("Calculation overflow , number1 is ",number1," number2 is ",number2)
}
return ret return ret
} }
func Mul[NumType NumberType](number1 NumType, number2 NumType) NumType { func Mul[NumType NumberType](number1 NumType, number2 NumType) NumType {
ret := number1 * number2 ret, _ := MulSafe(number1, number2)
if number1 == 0 || number2 == 0 {
return ret
}
if ret / number2 == number1 {
return ret
}
log.SStack("Calculation overflow , number1 is ",number1," number2 is ",number2)
return ret return ret
} }
// 安全的求比例
func PercentRateSafe[NumType NumberType, OutNumType NumberType](maxValue int64, rate NumType, numbers ...NumType) (OutNumType, bool) {
// 比例不能为负数
if rate < 0 {
log.Stack("rate must not positive")
return 0, false
}
if rate == 0 {
// 比例为0
return 0, true
}
ret := int64(rate)
for _, number := range numbers {
number64 := int64(number)
result, success := MulSafe(number64, ret)
if !success {
// 基数*比例越界了int64都越界了没办法了
return 0, false
}
ret = result
}
ret = ret / 10000
if ret > maxValue {
return 0, false
}
return OutNumType(ret), true
}

View File

@@ -0,0 +1,25 @@
package sysprocess
import (
"github.com/shirou/gopsutil/process"
"os"
)
func GetProcessNameByPID(pid int32) (string, error) {
proc, err := process.NewProcess(pid)
if err != nil {
return "", err
}
processName, err := proc.Name()
if err != nil {
return "", err
}
return processName, nil
}
func GetMyProcessName() (string, error) {
return GetProcessNameByPID(int32(os.Getpid()))
}

View File

@@ -7,6 +7,7 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"time" "time"
"sync/atomic"
) )
// ITimer // ITimer
@@ -29,7 +30,7 @@ type OnAddTimer func(timer ITimer)
// Timer // Timer
type Timer struct { type Timer struct {
Id uint64 Id uint64
cancelled bool //是否关闭 cancelled int32 //是否关闭
C chan ITimer //定时器管道 C chan ITimer //定时器管道
interval time.Duration // 时间间隔(用于循环定时器) interval time.Duration // 时间间隔(用于循环定时器)
fireTime time.Time // 触发时间 fireTime time.Time // 触发时间
@@ -131,7 +132,7 @@ func (t *Timer) Do() {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -171,12 +172,12 @@ func (t *Timer) GetInterval() time.Duration {
} }
func (t *Timer) Cancel() { func (t *Timer) Cancel() {
t.cancelled = true atomic.StoreInt32(&t.cancelled,1)
} }
// 判断定时器是否已经取消 // 判断定时器是否已经取消
func (t *Timer) IsActive() bool { func (t *Timer) IsActive() bool {
return !t.cancelled return atomic.LoadInt32(&t.cancelled) == 0
} }
func (t *Timer) GetName() string { func (t *Timer) GetName() string {
@@ -217,7 +218,7 @@ func (c *Cron) Do() {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()
@@ -273,7 +274,7 @@ func (c *Ticker) Do() {
buf := make([]byte, 4096) buf := make([]byte, 4096)
l := runtime.Stack(buf, false) l := runtime.Stack(buf, false)
errString := fmt.Sprint(r) errString := fmt.Sprint(r)
log.SError("core dump info[", errString, "]\n", string(buf[:l])) log.Dump(string(buf[:l]),log.String("error",errString))
} }
}() }()