mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-05 07:24:57 +08:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ea51ccfd8 | ||
|
|
5275db92bd | ||
|
|
19fd24d9db | ||
|
|
258a6821da | ||
|
|
7780947a96 | ||
|
|
4c169cf0bb | ||
|
|
96d02c8f71 | ||
|
|
3a56282a0b | ||
|
|
c9f30305ce | ||
|
|
9689b7b5fe | ||
|
|
eebbef52c9 | ||
|
|
2ddc54f5ac | ||
|
|
75ef7302de | ||
|
|
ecea9d1706 | ||
|
|
4898116698 | ||
|
|
bcbee6dd11 | ||
|
|
43122190a3 | ||
|
|
39b862e3d9 | ||
|
|
8c9b796fce | ||
|
|
c0971a46a7 | ||
|
|
ba019ac466 | ||
|
|
c803b9b9ad | ||
|
|
3f52ea8331 | ||
|
|
2d1bee4dea | ||
|
|
fa8cbfb40e | ||
|
|
388b946401 | ||
|
|
582a0faa6f | ||
|
|
fa6039e2cb | ||
|
|
25a672ca53 | ||
|
|
75f881be28 | ||
|
|
ef8182eec7 | ||
|
|
4ad8204fde | ||
|
|
8f15546fb1 | ||
|
|
0f3a965d73 | ||
|
|
dfb6959843 | ||
|
|
dd4aaf9c57 | ||
|
|
6ef98a2104 | ||
|
|
1890b300ee | ||
|
|
6fea2226e1 | ||
|
|
ec1c2b4517 | ||
|
|
4b84d9a1d5 | ||
|
|
85a8ec58e5 | ||
|
|
962016d476 | ||
|
|
a61979e985 |
63
README.md
63
README.md
@@ -19,7 +19,7 @@ Hello world!
|
||||
```go
|
||||
go get -v -u github.com/duanhf2012/origin
|
||||
```
|
||||
|
||||
[README.md](README.md)
|
||||
于是下载到GOPATH环境目录中,在src中加入main.go,内容如下:
|
||||
|
||||
```go
|
||||
@@ -64,17 +64,19 @@ cluster.json如下:
|
||||
"Private": false,
|
||||
"ListenAddr":"127.0.0.1:8001",
|
||||
"MaxRpcParamLen": 409600,
|
||||
"CompressBytesLen": 20480,
|
||||
"NodeName": "Node_Test1",
|
||||
"remark":"//以_打头的,表示只在本机进程,不对整个子网公开",
|
||||
"remark":"//以_打头的,表示只在本机进程,不对整个子网公开",
|
||||
"ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","_TcpService","HttpService","WSService"]
|
||||
},
|
||||
{
|
||||
{
|
||||
"NodeId": 2,
|
||||
"Private": false,
|
||||
"ListenAddr":"127.0.0.1:8002",
|
||||
"MaxRpcParamLen": 409600,
|
||||
"CompressBytesLen": 20480,
|
||||
"NodeName": "Node_Test1",
|
||||
"remark":"//以_打头的,表示只在本机进程,不对整个子网公开",
|
||||
"remark":"//以_打头的,表示只在本机进程,不对整个子网公开",
|
||||
"ServiceList": ["TestService1","TestService2","TestServiceCall","GateService","TcpService","HttpService","WSService"]
|
||||
}
|
||||
]
|
||||
@@ -88,6 +90,7 @@ cluster.json如下:
|
||||
* Private: 是否私有结点,如果为true,表示其他结点不会发现它,但可以自我运行。
|
||||
* ListenAddr:Rpc通信服务的监听地址
|
||||
* MaxRpcParamLen:Rpc参数数据包最大长度,该参数可以缺省,默认一次Rpc调用支持最大4294967295byte长度数据。
|
||||
* CompressBytesLen:Rpc网络数据压缩,当数据>=20480byte时将被压缩。该参数可以缺省或者填0时不进行压缩。
|
||||
* NodeName:结点名称
|
||||
* remark:备注,可选项
|
||||
* ServiceList:该Node拥有的服务列表,注意:origin按配置的顺序进行安装初始化。但停止服务的顺序是相反。
|
||||
@@ -715,6 +718,15 @@ func (slf *TestService7) CallTest(){
|
||||
}else{
|
||||
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返回值
|
||||
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 {
|
||||
fmt.Printf("AsyncCall error :%+v\n",err)
|
||||
}else{
|
||||
fmt.Printf("AsyncCall output %d\n",*output)
|
||||
fmt.Printf("AsyncCall error :%+v\n", err)
|
||||
} else {
|
||||
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(){
|
||||
@@ -832,8 +858,7 @@ origin引擎默认使用读取所有结点配置的进行确认结点有哪些Se
|
||||
"MasterDiscoveryNode": [{
|
||||
"NodeId": 2,
|
||||
"ListenAddr": "127.0.0.1:10001",
|
||||
"MaxRpcParamLen": 409600,
|
||||
"NeighborService":["HttpGateService"]
|
||||
"MaxRpcParamLen": 409600
|
||||
},
|
||||
{
|
||||
"NodeId": 1,
|
||||
@@ -850,17 +875,18 @@ origin引擎默认使用读取所有结点配置的进行确认结点有哪些Se
|
||||
"Private": false,
|
||||
"remark": "//以_打头的,表示只在本机进程,不对整个子网开发",
|
||||
"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。其中:
|
||||
|
||||
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不配置,则筛选功能不生效。
|
||||
MasterDiscoveryService: 表示将筛选origin网络中MasterNodeId为2中的TestService8服务,注意如果MasterDiscoveryService不配置,则筛选功能不生效。MasterNodeId也可以填为0,表示NodeId为1的结点,在所有网络中只发现TestService8的服务。
|
||||
|
||||
第八章:HttpService使用
|
||||
-----------------------
|
||||
@@ -1036,7 +1062,7 @@ func (slf *TestTcpService) OnRequest (clientid uint64,msg proto.Message){
|
||||
提交bug及特性: https://github.com/duanhf2012/origin/issues
|
||||
|
||||
[因服务器是由个人维护,如果这个项目对您有帮助,您可以点我进行捐赠,感谢!](http://www.cppblog.com/images/cppblog_com/API/21416/r_pay.jpg "Thanks!")
|
||||
|
||||

|
||||
特别感谢以下赞助网友:
|
||||
|
||||
```
|
||||
@@ -1045,4 +1071,5 @@ _
|
||||
死磕代码
|
||||
bp-li
|
||||
阿正
|
||||
大头
|
||||
```
|
||||
|
||||
@@ -20,17 +20,23 @@ const (
|
||||
Discard NodeStatus = 1 //丢弃
|
||||
)
|
||||
|
||||
type MasterDiscoveryService struct {
|
||||
MasterNodeId int32 //要筛选的主结点Id,如果不配置或者配置成0,表示针对所有的主结点
|
||||
DiscoveryService []string //只发现的服务列表
|
||||
}
|
||||
|
||||
type NodeInfo struct {
|
||||
NodeId int
|
||||
NodeName string
|
||||
Private bool
|
||||
ListenAddr string
|
||||
MaxRpcParamLen uint32 //最大Rpc参数长度
|
||||
CompressBytesLen int //超过字节进行压缩的长度
|
||||
ServiceList []string //所有的有序服务列表
|
||||
PublicServiceList []string //对外公开的服务列表
|
||||
DiscoveryService []string //筛选发现的服务,如果不配置,不进行筛选
|
||||
NeighborService []string
|
||||
MasterDiscoveryService []MasterDiscoveryService //筛选发现的服务,如果不配置,不进行筛选
|
||||
status NodeStatus
|
||||
Retire bool
|
||||
}
|
||||
|
||||
type NodeRpcInfo struct {
|
||||
@@ -50,8 +56,8 @@ type Cluster struct {
|
||||
|
||||
|
||||
locker sync.RWMutex //结点与服务关系保护锁
|
||||
mapRpc map[int]NodeRpcInfo //nodeId
|
||||
mapIdNode map[int]NodeInfo //map[NodeId]NodeInfo
|
||||
mapRpc map[int]*NodeRpcInfo //nodeId
|
||||
//mapIdNode map[int]NodeInfo //map[NodeId]NodeInfo
|
||||
mapServiceNode map[string]map[int]struct{} //map[serviceName]map[NodeId]
|
||||
|
||||
rpcServer rpc.Server
|
||||
@@ -73,7 +79,7 @@ func SetServiceDiscovery(serviceDiscovery IServiceDiscovery) {
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -82,10 +88,11 @@ func (cls *Cluster) Stop() {
|
||||
|
||||
func (cls *Cluster) DiscardNode(nodeId int) {
|
||||
cls.locker.Lock()
|
||||
nodeInfo, ok := cls.mapIdNode[nodeId]
|
||||
nodeInfo, ok := cls.mapRpc[nodeId]
|
||||
bDel := (ok == true) && nodeInfo.nodeInfo.status == Discard
|
||||
cls.locker.Unlock()
|
||||
|
||||
if ok == true && nodeInfo.status == Discard {
|
||||
if bDel {
|
||||
cls.DelNode(nodeId, true)
|
||||
}
|
||||
}
|
||||
@@ -98,39 +105,30 @@ func (cls *Cluster) DelNode(nodeId int, immediately bool) {
|
||||
cls.locker.Lock()
|
||||
defer cls.locker.Unlock()
|
||||
|
||||
nodeInfo, ok := cls.mapIdNode[nodeId]
|
||||
rpc, ok := cls.mapRpc[nodeId]
|
||||
if ok == false {
|
||||
return
|
||||
}
|
||||
|
||||
rpc, ok := cls.mapRpc[nodeId]
|
||||
for {
|
||||
//立即删除
|
||||
if immediately || ok == false {
|
||||
break
|
||||
}
|
||||
|
||||
if immediately ==false {
|
||||
//正在连接中不主动断开,只断开没有连接中的
|
||||
if rpc.client.IsConnected() {
|
||||
nodeInfo.status = Discard
|
||||
log.SRelease("Discard node ", nodeInfo.NodeId, " ", nodeInfo.ListenAddr)
|
||||
rpc.nodeInfo.status = Discard
|
||||
log.Info("Discard node",log.Int("nodeId",rpc.nodeInfo.NodeId),log.String("ListenAddr", rpc.nodeInfo.ListenAddr))
|
||||
return
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
for _, serviceName := range nodeInfo.ServiceList {
|
||||
for _, serviceName := range rpc.nodeInfo.ServiceList {
|
||||
cls.delServiceNode(serviceName, nodeId)
|
||||
}
|
||||
|
||||
delete(cls.mapIdNode, nodeId)
|
||||
delete(cls.mapRpc, nodeId)
|
||||
if ok == true {
|
||||
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) {
|
||||
@@ -163,9 +161,9 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
|
||||
defer cls.locker.Unlock()
|
||||
|
||||
//先清一次的NodeId对应的所有服务清理
|
||||
lastNodeInfo, ok := cls.mapIdNode[nodeInfo.NodeId]
|
||||
lastNodeInfo, ok := cls.mapRpc[nodeInfo.NodeId]
|
||||
if ok == true {
|
||||
for _, serviceName := range lastNodeInfo.ServiceList {
|
||||
for _, serviceName := range lastNodeInfo.nodeInfo.ServiceList {
|
||||
cls.delServiceNode(serviceName, nodeInfo.NodeId)
|
||||
}
|
||||
}
|
||||
@@ -175,7 +173,7 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
|
||||
for _, serviceName := range nodeInfo.PublicServiceList {
|
||||
if _, ok := mapDuplicate[serviceName]; ok == true {
|
||||
//存在重复
|
||||
log.SError("Bad duplicate Service Cfg.")
|
||||
log.Error("Bad duplicate Service Cfg.")
|
||||
continue
|
||||
}
|
||||
mapDuplicate[serviceName] = nil
|
||||
@@ -184,28 +182,22 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
|
||||
}
|
||||
cls.mapServiceNode[serviceName][nodeInfo.NodeId] = struct{}{}
|
||||
}
|
||||
cls.mapIdNode[nodeInfo.NodeId] = *nodeInfo
|
||||
|
||||
log.SRelease("Discovery nodeId: ", nodeInfo.NodeId, " services:", nodeInfo.PublicServiceList)
|
||||
|
||||
//已经存在连接,则不需要进行设置
|
||||
if _, rpcInfoOK := cls.mapRpc[nodeInfo.NodeId]; rpcInfoOK == true {
|
||||
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
|
||||
return
|
||||
}
|
||||
|
||||
//不存在时,则建立连接
|
||||
rpcInfo := NodeRpcInfo{}
|
||||
rpcInfo.nodeInfo = *nodeInfo
|
||||
rpcInfo.client =rpc.NewRClient(nodeInfo.NodeId, nodeInfo.ListenAddr, nodeInfo.MaxRpcParamLen,cls.triggerRpcEvent)
|
||||
cls.mapRpc[nodeInfo.NodeId] = rpcInfo
|
||||
rpcInfo.client =rpc.NewRClient(nodeInfo.NodeId, nodeInfo.ListenAddr, nodeInfo.MaxRpcParamLen,cls.localNodeInfo.CompressBytesLen,cls.triggerRpcEvent)
|
||||
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 {
|
||||
//1.初始化配置
|
||||
@@ -215,7 +207,6 @@ func (cls *Cluster) Init(localNodeId int, setupServiceFun SetupServiceFun) error
|
||||
}
|
||||
|
||||
cls.rpcServer.Init(cls)
|
||||
cls.buildLocalRpc()
|
||||
|
||||
//2.安装服务发现结点
|
||||
cls.SetupServiceDiscovery(localNodeId, setupServiceFun)
|
||||
@@ -309,27 +300,33 @@ func (cls *Cluster) FindRpcHandler(serviceName string) rpc.IRpcHandler {
|
||||
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]
|
||||
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()
|
||||
defer cls.locker.RUnlock()
|
||||
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 {
|
||||
pClient := GetCluster().GetRpcClient(nodeId)
|
||||
pClient,retire := GetCluster().GetRpcClient(nodeId)
|
||||
if pClient == nil {
|
||||
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
|
||||
return nil, 1
|
||||
}
|
||||
@@ -341,7 +338,7 @@ func GetRpcClient(nodeId int, serviceMethod string, clientList []*rpc.Client) (e
|
||||
serviceName := serviceMethod[:findIndex]
|
||||
|
||||
//1.找到对应的rpcNodeid
|
||||
return GetCluster().GetNodeIdByService(serviceName, clientList, true)
|
||||
return GetCluster().GetNodeIdByService(serviceName, clientList, filterRetire)
|
||||
}
|
||||
|
||||
func GetRpcServer() *rpc.Server {
|
||||
@@ -349,10 +346,19 @@ func GetRpcServer() *rpc.Server {
|
||||
}
|
||||
|
||||
func (cls *Cluster) IsNodeConnected(nodeId int) bool {
|
||||
pClient := cls.GetRpcClient(nodeId)
|
||||
pClient,_ := cls.GetRpcClient(nodeId)
|
||||
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) {
|
||||
cls.locker.Lock()
|
||||
nodeInfo, ok := cls.mapRpc[nodeId]
|
||||
@@ -367,7 +373,7 @@ func (cls *Cluster) triggerRpcEvent(bConnect bool, clientId uint32, nodeId int)
|
||||
for serviceName, _ := range cls.mapServiceListenRpcEvent {
|
||||
ser := service.GetService(serviceName)
|
||||
if ser == nil {
|
||||
log.SError("cannot find service name ", serviceName)
|
||||
log.Error("cannot find service name "+serviceName)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -385,7 +391,7 @@ func (cls *Cluster) TriggerDiscoveryEvent(bDiscovery bool, nodeId int, serviceNa
|
||||
for sName, _ := range cls.mapServiceListenDiscoveryEvent {
|
||||
ser := service.GetService(sName)
|
||||
if ser == nil {
|
||||
log.SError("cannot find service name ", serviceName)
|
||||
log.Error("cannot find service",log.Any("services",serviceName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -471,11 +477,14 @@ func (cls *Cluster) GetGlobalCfg() interface{} {
|
||||
return cls.globalCfg
|
||||
}
|
||||
|
||||
|
||||
func (cls *Cluster) GetNodeInfo(nodeId int) (NodeInfo,bool) {
|
||||
cls.locker.RLock()
|
||||
defer cls.locker.RUnlock()
|
||||
|
||||
nodeInfo,ok:= cls.mapIdNode[nodeId]
|
||||
return nodeInfo,ok
|
||||
nodeInfo,ok:= cls.mapRpc[nodeId]
|
||||
if ok == false || nodeInfo == nil {
|
||||
return NodeInfo{},false
|
||||
}
|
||||
|
||||
return nodeInfo.nodeInfo,true
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
"github.com/duanhf2012/origin/log"
|
||||
"github.com/duanhf2012/origin/rpc"
|
||||
"github.com/duanhf2012/origin/service"
|
||||
"time"
|
||||
"github.com/duanhf2012/origin/util/timer"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const DynamicDiscoveryMasterName = "DiscoveryMaster"
|
||||
@@ -12,6 +15,7 @@ const DynamicDiscoveryClientName = "DiscoveryClient"
|
||||
const RegServiceDiscover = DynamicDiscoveryMasterName + ".RPC_RegServiceDiscover"
|
||||
const SubServiceDiscover = DynamicDiscoveryClientName + ".RPC_SubServiceDiscover"
|
||||
const AddSubServiceDiscover = DynamicDiscoveryMasterName + ".RPC_AddSubServiceDiscover"
|
||||
const NodeRetireRpcMethod = DynamicDiscoveryMasterName+".RPC_NodeRetire"
|
||||
|
||||
type DynamicDiscoveryMaster struct {
|
||||
service.Service
|
||||
@@ -28,6 +32,7 @@ type DynamicDiscoveryClient struct {
|
||||
localNodeId int
|
||||
|
||||
mapDiscovery map[int32]map[int32]struct{} //map[masterNodeId]map[nodeId]struct{}
|
||||
bRetire bool
|
||||
}
|
||||
|
||||
var masterService DynamicDiscoveryMaster
|
||||
@@ -47,16 +52,32 @@ func (ds *DynamicDiscoveryMaster) isRegNode(nodeId int32) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func (ds *DynamicDiscoveryMaster) addNodeInfo(nodeInfo *rpc.NodeInfo) {
|
||||
if len(nodeInfo.PublicServiceList) == 0 {
|
||||
func (ds *DynamicDiscoveryMaster) updateNodeInfo(nInfo *rpc.NodeInfo) {
|
||||
if _,ok:= ds.mapNodeInfo[nInfo.NodeId];ok == false {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
ds.mapNodeInfo[nodeInfo.NodeId] = struct{}{}
|
||||
ds.mapNodeInfo[nInfo.NodeId] = struct{}{}
|
||||
|
||||
nodeInfo := proto.Clone(nInfo).(*rpc.NodeInfo)
|
||||
ds.nodeInfo = append(ds.nodeInfo, nodeInfo)
|
||||
}
|
||||
|
||||
@@ -85,16 +106,14 @@ func (ds *DynamicDiscoveryMaster) OnInit() error {
|
||||
func (ds *DynamicDiscoveryMaster) OnStart() {
|
||||
var nodeInfo rpc.NodeInfo
|
||||
localNodeInfo := cluster.GetLocalNodeInfo()
|
||||
if localNodeInfo.Private == true {
|
||||
return
|
||||
}
|
||||
|
||||
nodeInfo.NodeId = int32(localNodeInfo.NodeId)
|
||||
nodeInfo.NodeName = localNodeInfo.NodeName
|
||||
nodeInfo.ListenAddr = localNodeInfo.ListenAddr
|
||||
nodeInfo.PublicServiceList = localNodeInfo.PublicServiceList
|
||||
nodeInfo.MaxRpcParamLen = localNodeInfo.MaxRpcParamLen
|
||||
|
||||
nodeInfo.Private = localNodeInfo.Private
|
||||
nodeInfo.Retire = localNodeInfo.Retire
|
||||
|
||||
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, ¬ifyDiscover)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 收到注册过来的结点
|
||||
func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscoverReq, res *rpc.Empty) error {
|
||||
if req.NodeInfo == nil {
|
||||
err := errors.New("RPC_RegServiceDiscover req is error.")
|
||||
log.SError(err.Error())
|
||||
log.Error(err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -163,6 +195,8 @@ func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscove
|
||||
nodeInfo.PublicServiceList = req.NodeInfo.PublicServiceList
|
||||
nodeInfo.ListenAddr = req.NodeInfo.ListenAddr
|
||||
nodeInfo.MaxRpcParamLen = req.NodeInfo.MaxRpcParamLen
|
||||
nodeInfo.Retire = req.NodeInfo.Retire
|
||||
|
||||
//主动删除已经存在的结点,确保先断开,再连接
|
||||
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 {
|
||||
//整理当前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{}
|
||||
for _, nodeInfo := range req.NodeInfo {
|
||||
//不对本地结点或者不存在任何公开服务的结点
|
||||
@@ -269,13 +294,6 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
||||
|
||||
//遍历所有的公开服务,并筛选之
|
||||
for _, serviceName := range nodeInfo.PublicServiceList {
|
||||
//只有存在配置时才做筛选
|
||||
if len(mapMasterDiscoveryService) > 0 {
|
||||
if _, ok := mapMasterDiscoveryService[serviceName]; ok == false {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
nInfo := mapNodeInfo[nodeInfo.NodeId]
|
||||
if nInfo == nil {
|
||||
nInfo = &rpc.NodeInfo{}
|
||||
@@ -283,6 +301,9 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
||||
nInfo.NodeName = nodeInfo.NodeName
|
||||
nInfo.ListenAddr = nodeInfo.ListenAddr
|
||||
nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen
|
||||
nInfo.Retire = nodeInfo.Retire
|
||||
nInfo.Private = nodeInfo.Private
|
||||
|
||||
mapNodeInfo[nodeInfo.NodeId] = nInfo
|
||||
}
|
||||
|
||||
@@ -292,7 +313,6 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
||||
|
||||
//如果为完整同步,则找出差异的结点
|
||||
var willDelNodeId []int32
|
||||
//如果不是邻居结点,则做筛选
|
||||
if req.IsFull == true {
|
||||
diffNode := dc.fullCompareDiffNode(req.MasterNodeId, mapNodeInfo)
|
||||
if len(diffNode) > 0 {
|
||||
@@ -307,8 +327,7 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
||||
|
||||
//删除不必要的结点
|
||||
for _, nodeId := range willDelNodeId {
|
||||
nodeInfo,_ := cluster.GetNodeInfo(int(nodeId))
|
||||
cluster.TriggerDiscoveryEvent(false,int(nodeId),nodeInfo.PublicServiceList)
|
||||
cluster.TriggerDiscoveryEvent(false,int(nodeId),nil)
|
||||
dc.removeMasterNode(req.MasterNodeId, int32(nodeId))
|
||||
if dc.findNodeId(nodeId) == false {
|
||||
dc.funDelService(int(nodeId), false)
|
||||
@@ -317,10 +336,8 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
||||
|
||||
//设置新结点
|
||||
for _, nodeInfo := range mapNodeInfo {
|
||||
dc.addMasterNode(req.MasterNodeId, nodeInfo.NodeId)
|
||||
dc.setNodeInfo(nodeInfo)
|
||||
|
||||
if len(nodeInfo.PublicServiceList) == 0 {
|
||||
bSet := dc.setNodeInfo(req.MasterNodeId,nodeInfo)
|
||||
if bSet == false {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -341,6 +358,33 @@ func (dc *DynamicDiscoveryClient) isDiscoverNode(nodeId int) bool {
|
||||
}
|
||||
|
||||
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)
|
||||
if nodeInfo == nil {
|
||||
return
|
||||
@@ -352,57 +396,76 @@ func (dc *DynamicDiscoveryClient) OnNodeConnected(nodeId int) {
|
||||
req.NodeInfo.NodeName = cluster.localNodeInfo.NodeName
|
||||
req.NodeInfo.ListenAddr = cluster.localNodeInfo.ListenAddr
|
||||
req.NodeInfo.MaxRpcParamLen = cluster.localNodeInfo.MaxRpcParamLen
|
||||
|
||||
//MasterDiscoveryNode配置中没有配置NeighborService,则同步当前结点所有服务
|
||||
if len(nodeInfo.NeighborService) == 0 {
|
||||
req.NodeInfo.PublicServiceList = cluster.localNodeInfo.PublicServiceList
|
||||
} else {
|
||||
req.NodeInfo.PublicServiceList = append(req.NodeInfo.PublicServiceList, DynamicDiscoveryClientName)
|
||||
}
|
||||
req.NodeInfo.PublicServiceList = cluster.localNodeInfo.PublicServiceList
|
||||
req.NodeInfo.Retire = dc.bRetire
|
||||
req.NodeInfo.Private = cluster.localNodeInfo.Private
|
||||
|
||||
//向Master服务同步本Node服务信息
|
||||
err := dc.AsyncCallNode(nodeId, RegServiceDiscover, &req, func(res *rpc.Empty, err error) {
|
||||
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
|
||||
}
|
||||
})
|
||||
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) {
|
||||
if nodeInfo == nil || nodeInfo.Private == true || int(nodeInfo.NodeId) == dc.localNodeId {
|
||||
return
|
||||
}
|
||||
func (dc *DynamicDiscoveryClient) canDiscoveryService(fromMasterNodeId int32,serviceName string) bool{
|
||||
canDiscovery := true
|
||||
|
||||
//筛选关注的服务
|
||||
localNodeInfo := cluster.GetLocalNodeInfo()
|
||||
if len(localNodeInfo.DiscoveryService) > 0 {
|
||||
var discoverServiceSlice = make([]string, 0, 24)
|
||||
for _, pubService := range nodeInfo.PublicServiceList {
|
||||
for _, discoverService := range localNodeInfo.DiscoveryService {
|
||||
if pubService == discoverService {
|
||||
discoverServiceSlice = append(discoverServiceSlice, pubService)
|
||||
for i:=0;i<len(cluster.GetLocalNodeInfo().MasterDiscoveryService);i++{
|
||||
masterNodeId := cluster.GetLocalNodeInfo().MasterDiscoveryService[i].MasterNodeId
|
||||
|
||||
if masterNodeId == fromMasterNodeId || masterNodeId == 0 {
|
||||
canDiscovery = false
|
||||
|
||||
for _,discoveryService := range cluster.GetLocalNodeInfo().MasterDiscoveryService[i].DiscoveryService {
|
||||
if discoveryService == serviceName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
nodeInfo.PublicServiceList = discoverServiceSlice
|
||||
}
|
||||
|
||||
if len(nodeInfo.PublicServiceList) == 0 {
|
||||
return
|
||||
return canDiscovery
|
||||
}
|
||||
|
||||
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
|
||||
nInfo.ServiceList = nodeInfo.PublicServiceList
|
||||
nInfo.PublicServiceList = nodeInfo.PublicServiceList
|
||||
nInfo.ServiceList = discoverServiceSlice
|
||||
nInfo.PublicServiceList = discoverServiceSlice
|
||||
nInfo.NodeId = int(nodeInfo.NodeId)
|
||||
nInfo.NodeName = nodeInfo.NodeName
|
||||
nInfo.ListenAddr = nodeInfo.ListenAddr
|
||||
nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen
|
||||
nInfo.Retire = nodeInfo.Retire
|
||||
nInfo.Private = nodeInfo.Private
|
||||
|
||||
dc.funSetService(&nInfo)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (dc *DynamicDiscoveryClient) OnNodeDisconnect(nodeId int) {
|
||||
|
||||
@@ -58,7 +58,7 @@ func (cls *Cluster) readServiceConfig(filepath string) (interface{}, map[string]
|
||||
serviceCfg := v.(map[string]interface{})
|
||||
nodeId, ok := serviceCfg["NodeId"]
|
||||
if ok == false {
|
||||
log.SFatal("NodeService list not find nodeId field")
|
||||
log.Fatal("NodeService list not find nodeId field")
|
||||
}
|
||||
mapNodeService[int(nodeId.(float64))] = serviceCfg
|
||||
}
|
||||
@@ -199,7 +199,11 @@ func (cls *Cluster) readLocalService(localNodeId int) error {
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
cls.localServiceCfg = map[string]interface{}{}
|
||||
cls.mapRpc = map[int]NodeRpcInfo{}
|
||||
cls.mapIdNode = map[int]NodeInfo{}
|
||||
cls.mapRpc = map[int]*NodeRpcInfo{}
|
||||
cls.mapServiceNode = map[string]map[int]struct{}{}
|
||||
|
||||
//加载本地结点的NodeList配置
|
||||
@@ -263,17 +266,24 @@ func (cls *Cluster) IsConfigService(serviceName string) bool {
|
||||
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()
|
||||
defer cls.locker.RUnlock()
|
||||
mapNodeId, ok := cls.mapServiceNode[serviceName]
|
||||
count := 0
|
||||
if ok == true {
|
||||
for nodeId, _ := range mapNodeId {
|
||||
pClient := GetCluster().getRpcClient(nodeId)
|
||||
if pClient == nil || (bAll == false && pClient.IsConnected() == false) {
|
||||
pClient,retire := GetCluster().getRpcClient(nodeId)
|
||||
if pClient == nil || pClient.IsConnected() == false {
|
||||
continue
|
||||
}
|
||||
|
||||
//如果需要筛选掉退休的,对retire状态的结点略过
|
||||
if filterRetire == true && retire == true {
|
||||
continue
|
||||
}
|
||||
|
||||
rpcClientList[count] = pClient
|
||||
count++
|
||||
if count >= cap(rpcClientList) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/duanhf2012/origin/log"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
const defaultMaxTaskChannelNum = 1000000
|
||||
@@ -21,6 +22,7 @@ type Concurrent struct {
|
||||
|
||||
tasks chan task
|
||||
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) {
|
||||
if atomic.AddInt32(&c.open,1) > 1 {
|
||||
panic("repeated calls to OpenConcurrent are not allowed!")
|
||||
}
|
||||
|
||||
c.tasks = make(chan task, 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 {
|
||||
log.SStack("fn and cb is nil")
|
||||
log.Stack("fn and cb is nil")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -66,7 +72,7 @@ func (c *Concurrent) AsyncDoByQueue(queueId int64, fn func() bool, cb func(err e
|
||||
select {
|
||||
case c.tasks <- task{queueId, fn, cb}:
|
||||
default:
|
||||
log.SError("tasks channel is full")
|
||||
log.Error("tasks channel is full")
|
||||
if cb != nil {
|
||||
c.pushAsyncDoCallbackEvent(func(err error) {
|
||||
cb(errors.New("tasks channel is full"))
|
||||
@@ -81,11 +87,11 @@ func (c *Concurrent) Close() {
|
||||
return
|
||||
}
|
||||
|
||||
log.SRelease("wait close concurrent")
|
||||
log.Info("wait close concurrent")
|
||||
|
||||
c.dispatch.close()
|
||||
|
||||
log.SRelease("concurrent has successfully exited")
|
||||
log.Info("concurrent has successfully exited")
|
||||
}
|
||||
|
||||
func (c *Concurrent) GetCallBackChannel() chan func(error) {
|
||||
|
||||
@@ -187,8 +187,7 @@ func (d *dispatch) DoCallback(cb func(err error)) {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
errString := fmt.Sprint(r)
|
||||
|
||||
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ func (w *worker) run(waitGroup *sync.WaitGroup, t task) {
|
||||
case tw := <-w.workerQueue:
|
||||
if tw.isExistTask() {
|
||||
//exit goroutine
|
||||
log.SRelease("worker goroutine exit")
|
||||
log.Info("worker goroutine exit")
|
||||
return
|
||||
}
|
||||
w.exec(&tw)
|
||||
@@ -59,9 +59,8 @@ func (w *worker) exec(t *task) {
|
||||
t.cb = func(err error) {
|
||||
cb(errors.New(errString))
|
||||
}
|
||||
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
w.endCallFun(true,t)
|
||||
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ type CommandFunctionCB func(args interface{}) error
|
||||
var commandList []*command
|
||||
var programName string
|
||||
const(
|
||||
boolType valueType = iota
|
||||
stringType valueType = iota
|
||||
boolType valueType = 0
|
||||
stringType valueType = 1
|
||||
intType valueType = 2
|
||||
)
|
||||
|
||||
type command struct{
|
||||
@@ -20,6 +21,7 @@ type command struct{
|
||||
name string
|
||||
bValue bool
|
||||
strValue string
|
||||
intValue int
|
||||
usage string
|
||||
fn CommandFunctionCB
|
||||
}
|
||||
@@ -29,6 +31,8 @@ func (cmd *command) execute() error{
|
||||
return cmd.fn(cmd.bValue)
|
||||
}else if cmd.valType == stringType {
|
||||
return cmd.fn(cmd.strValue)
|
||||
}else if cmd.valType == intType {
|
||||
return cmd.fn(cmd.intValue)
|
||||
}else{
|
||||
return fmt.Errorf("Unknow command type.")
|
||||
}
|
||||
@@ -72,6 +76,16 @@ func RegisterCommandBool(cmdName string, defaultValue bool, usage string,fn Comm
|
||||
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){
|
||||
var cmd command
|
||||
cmd.valType = stringType
|
||||
|
||||
@@ -215,7 +215,7 @@ func (processor *EventProcessor) EventHandler(ev IEvent) {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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){
|
||||
if processor.mapListenerEvent == nil {
|
||||
log.SError("mapListenerEvent not init!")
|
||||
log.Error("mapListenerEvent not init!")
|
||||
return
|
||||
}
|
||||
|
||||
eventProcessor,ok := processor.mapListenerEvent[event.GetEventType()]
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -7,16 +7,15 @@ const (
|
||||
ServiceRpcRequestEvent EventType = -1
|
||||
ServiceRpcResponseEvent EventType = -2
|
||||
|
||||
Sys_Event_Tcp EventType = -3
|
||||
Sys_Event_Http_Event EventType = -4
|
||||
Sys_Event_WebSocket EventType = -5
|
||||
Sys_Event_Node_Event EventType = -6
|
||||
Sys_Event_DiscoverService EventType = -7
|
||||
Sys_Event_DiscardGoroutine EventType = -8
|
||||
Sys_Event_QueueTaskFinish EventType = -9
|
||||
|
||||
Sys_Event_User_Define EventType = 1
|
||||
|
||||
Sys_Event_Tcp EventType = -3
|
||||
Sys_Event_Http_Event EventType = -4
|
||||
Sys_Event_WebSocket EventType = -5
|
||||
Sys_Event_Node_Event EventType = -6
|
||||
Sys_Event_DiscoverService EventType = -7
|
||||
Sys_Event_DiscardGoroutine EventType = -8
|
||||
Sys_Event_QueueTaskFinish EventType = -9
|
||||
Sys_Event_Retire EventType = -10
|
||||
|
||||
Sys_Event_User_Define EventType = 1
|
||||
)
|
||||
|
||||
|
||||
11
go.mod
11
go.mod
@@ -1,30 +1,37 @@
|
||||
module github.com/duanhf2012/origin
|
||||
|
||||
go 1.19
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
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/gorilla/websocket v1.5.0
|
||||
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
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // 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/scram 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/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
golang.org/x/crypto v0.1.0 // 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
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
46
go.sum
46
go.sum
@@ -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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
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/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
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/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.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/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
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/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/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
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/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
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/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
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/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/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
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/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-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.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
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-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-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/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-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-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/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.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
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-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/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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
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 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -2,27 +2,20 @@ package log // import "go.uber.org/zap/buffer"
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const _size = 9216
|
||||
|
||||
type Buffer struct {
|
||||
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(){
|
||||
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.
|
||||
func (b *Buffer) AppendByte(v byte) {
|
||||
|
||||
147
log/handler.go
Normal file
147
log/handler.go
Normal 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]
|
||||
}
|
||||
}
|
||||
1007
log/log.go
1007
log/log.go
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@ func (slf *HttpServer) startListen() error {
|
||||
for _, caFile := range slf.caFileList {
|
||||
cer, err := tls.LoadX509KeyPair(caFile.CertFile, caFile.Keyfile)
|
||||
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
|
||||
}
|
||||
tlsCaList = append(tlsCaList, cer)
|
||||
@@ -74,7 +74,7 @@ func (slf *HttpServer) startListen() error {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package processor
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/duanhf2012/origin/network"
|
||||
"reflect"
|
||||
"github.com/duanhf2012/origin/log"
|
||||
"github.com/duanhf2012/origin/util/bytespool"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type MessageJsonInfo struct {
|
||||
@@ -24,7 +24,7 @@ type JsonProcessor struct {
|
||||
unknownMessageHandler UnknownMessageJsonHandler
|
||||
connectHandler ConnectJsonHandler
|
||||
disconnectHandler ConnectJsonHandler
|
||||
network.INetMempool
|
||||
bytespool.IBytesMempool
|
||||
}
|
||||
|
||||
type JsonPackInfo struct {
|
||||
@@ -35,7 +35,7 @@ type JsonPackInfo struct {
|
||||
|
||||
func NewJsonProcessor() *JsonProcessor {
|
||||
processor := &JsonProcessor{mapMsg:map[uint16]MessageJsonInfo{}}
|
||||
processor.INetMempool = network.NewMemAreaPool()
|
||||
processor.IBytesMempool = bytespool.NewMemAreaPool()
|
||||
|
||||
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) {
|
||||
typeStruct := struct {Type int `json:"typ"`}{}
|
||||
defer jsonProcessor.ReleaseByteSlice(data)
|
||||
defer jsonProcessor.ReleaseBytes(data)
|
||||
err := json.Unmarshal(data, &typeStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -106,7 +106,7 @@ func (jsonProcessor *JsonProcessor) MakeRawMsg(msgType uint16,msg []byte) *JsonP
|
||||
|
||||
func (jsonProcessor *JsonProcessor) UnknownMsgRoute(clientId uint64,msg interface{}){
|
||||
if jsonProcessor.unknownMessageHandler==nil {
|
||||
log.SDebug("Unknown message received from ",clientId)
|
||||
log.Debug("Unknown message",log.Uint64("clientId",clientId))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ package processor
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/duanhf2012/origin/network"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/duanhf2012/origin/util/bytespool"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ type PBProcessor struct {
|
||||
unknownMessageHandler UnknownMessageHandler
|
||||
connectHandler ConnectHandler
|
||||
disconnectHandler ConnectHandler
|
||||
network.INetMempool
|
||||
bytespool.IBytesMempool
|
||||
}
|
||||
|
||||
type PBPackInfo struct {
|
||||
@@ -37,7 +37,7 @@ type PBPackInfo struct {
|
||||
|
||||
func NewPBProcessor() *PBProcessor {
|
||||
processor := &PBProcessor{mapMsg: map[uint16]MessageInfo{}}
|
||||
processor.INetMempool = network.NewMemAreaPool()
|
||||
processor.IBytesMempool = bytespool.NewMemAreaPool()
|
||||
return processor
|
||||
}
|
||||
|
||||
@@ -67,7 +67,12 @@ func (pbProcessor *PBProcessor) MsgRoute(clientId uint64, msg interface{}) error
|
||||
|
||||
// must goroutine safe
|
||||
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
|
||||
if pbProcessor.LittleEndian == true {
|
||||
msgType = binary.LittleEndian.Uint16(data[:2])
|
||||
|
||||
@@ -40,29 +40,29 @@ func (client *TCPClient) init() {
|
||||
|
||||
if client.ConnNum <= 0 {
|
||||
client.ConnNum = 1
|
||||
log.SRelease("invalid ConnNum, reset to ", client.ConnNum)
|
||||
log.Info("invalid ConnNum",log.Int("reset", client.ConnNum))
|
||||
}
|
||||
if client.ConnectInterval <= 0 {
|
||||
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 {
|
||||
client.PendingWriteNum = 1000
|
||||
log.SRelease("invalid PendingWriteNum, reset to ", client.PendingWriteNum)
|
||||
log.Info("invalid PendingWriteNum",log.Int("reset",client.PendingWriteNum))
|
||||
}
|
||||
if client.ReadDeadline == 0 {
|
||||
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 {
|
||||
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 {
|
||||
log.SFatal("NewAgent must not be nil")
|
||||
log.Fatal("NewAgent must not be nil")
|
||||
}
|
||||
if client.cons != nil {
|
||||
log.SFatal("client is running")
|
||||
log.Fatal("client is running")
|
||||
}
|
||||
|
||||
if client.MinMsgLen == 0 {
|
||||
@@ -77,7 +77,7 @@ func (client *TCPClient) init() {
|
||||
maxMsgLen := client.MsgParser.getMaxMsgLen(client.LenMsgLen)
|
||||
if 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)
|
||||
@@ -102,7 +102,7 @@ func (client *TCPClient) dial() net.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)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func newTCPConn(conn net.Conn, pendingWriteNum int, msgParser *MsgParser,writeDe
|
||||
|
||||
conn.SetWriteDeadline(time.Now().Add(writeDeadline))
|
||||
_, err := conn.Write(b)
|
||||
tcpConn.msgParser.ReleaseByteSlice(b)
|
||||
tcpConn.msgParser.ReleaseBytes(b)
|
||||
|
||||
if err != nil {
|
||||
break
|
||||
@@ -92,7 +92,7 @@ func (tcpConn *TCPConn) GetRemoteIp() string {
|
||||
func (tcpConn *TCPConn) doWrite(b []byte) error{
|
||||
if len(tcpConn.writeChan) == cap(tcpConn.writeChan) {
|
||||
tcpConn.ReleaseReadMsg(b)
|
||||
log.SError("close conn: channel full")
|
||||
log.Error("close conn: channel full")
|
||||
tcpConn.doDestroy()
|
||||
return errors.New("close conn: channel full")
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func (tcpConn *TCPConn) ReadMsg() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (tcpConn *TCPConn) ReleaseReadMsg(byteBuff []byte){
|
||||
tcpConn.msgParser.ReleaseByteSlice(byteBuff)
|
||||
tcpConn.msgParser.ReleaseBytes(byteBuff)
|
||||
}
|
||||
|
||||
func (tcpConn *TCPConn) WriteMsg(args ...[]byte) error {
|
||||
|
||||
@@ -3,6 +3,7 @@ package network
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/duanhf2012/origin/util/bytespool"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
@@ -16,7 +17,7 @@ type MsgParser struct {
|
||||
MaxMsgLen uint32
|
||||
LittleEndian bool
|
||||
|
||||
INetMempool
|
||||
bytespool.IBytesMempool
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +35,7 @@ func (p *MsgParser) getMaxMsgLen(lenMsgLen int) uint32 {
|
||||
}
|
||||
|
||||
func (p *MsgParser) init(){
|
||||
p.INetMempool = NewMemAreaPool()
|
||||
p.IBytesMempool = bytespool.NewMemAreaPool()
|
||||
}
|
||||
|
||||
// goroutine safe
|
||||
@@ -74,9 +75,9 @@ func (p *MsgParser) Read(conn *TCPConn) ([]byte, error) {
|
||||
}
|
||||
|
||||
// data
|
||||
msgData := p.MakeByteSlice(int(msgLen))
|
||||
msgData := p.MakeBytes(int(msgLen))
|
||||
if _, err := io.ReadFull(conn, msgData[:msgLen]); err != nil {
|
||||
p.ReleaseByteSlice(msgData)
|
||||
p.ReleaseBytes(msgData)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -99,7 +100,7 @@ func (p *MsgParser) Write(conn *TCPConn, args ...[]byte) error {
|
||||
}
|
||||
|
||||
//msg := make([]byte, uint32(p.lenMsgLen)+msgLen)
|
||||
msg := p.MakeByteSlice(p.LenMsgLen+int(msgLen))
|
||||
msg := p.MakeBytes(p.LenMsgLen+int(msgLen))
|
||||
// write len
|
||||
switch p.LenMsgLen {
|
||||
case 1:
|
||||
|
||||
@@ -2,6 +2,7 @@ package network
|
||||
|
||||
import (
|
||||
"github.com/duanhf2012/origin/log"
|
||||
"github.com/duanhf2012/origin/util/bytespool"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -43,52 +44,52 @@ func (server *TCPServer) Start() {
|
||||
func (server *TCPServer) init() {
|
||||
ln, err := net.Listen("tcp", server.Addr)
|
||||
if err != nil {
|
||||
log.SFatal("Listen tcp error:", err.Error())
|
||||
log.Fatal("Listen tcp fail",log.String("error", err.Error()))
|
||||
}
|
||||
|
||||
if server.MaxConnNum <= 0 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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)
|
||||
if 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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
log.SFatal("NewAgent must not be nil")
|
||||
log.Fatal("NewAgent must not be nil")
|
||||
}
|
||||
|
||||
server.ln = ln
|
||||
@@ -96,12 +97,12 @@ func (server *TCPServer) init() {
|
||||
server.MsgParser.init()
|
||||
}
|
||||
|
||||
func (server *TCPServer) SetNetMempool(mempool INetMempool){
|
||||
server.INetMempool = mempool
|
||||
func (server *TCPServer) SetNetMempool(mempool bytespool.IBytesMempool){
|
||||
server.IBytesMempool = mempool
|
||||
}
|
||||
|
||||
func (server *TCPServer) GetNetMempool() INetMempool{
|
||||
return server.INetMempool
|
||||
func (server *TCPServer) GetNetMempool() bytespool.IBytesMempool {
|
||||
return server.IBytesMempool
|
||||
}
|
||||
|
||||
func (server *TCPServer) run() {
|
||||
@@ -121,7 +122,7 @@ func (server *TCPServer) run() {
|
||||
if max := 1 * time.Second; 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)
|
||||
continue
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (server *TCPServer) run() {
|
||||
if len(server.conns) >= server.MaxConnNum {
|
||||
server.mutexConns.Unlock()
|
||||
conn.Close()
|
||||
log.SWarning("too many connections")
|
||||
log.Warning("too many connections")
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -40,29 +40,29 @@ func (client *WSClient) init() {
|
||||
|
||||
if client.ConnNum <= 0 {
|
||||
client.ConnNum = 1
|
||||
log.SRelease("invalid ConnNum, reset to ", client.ConnNum)
|
||||
log.Info("invalid ConnNum",log.Int("reset", client.ConnNum))
|
||||
}
|
||||
if client.ConnectInterval <= 0 {
|
||||
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 {
|
||||
client.PendingWriteNum = 100
|
||||
log.SRelease("invalid PendingWriteNum, reset to ", client.PendingWriteNum)
|
||||
log.Info("invalid PendingWriteNum",log.Int("reset", client.PendingWriteNum))
|
||||
}
|
||||
if client.MaxMsgLen <= 0 {
|
||||
client.MaxMsgLen = 4096
|
||||
log.SRelease("invalid MaxMsgLen, reset to ", client.MaxMsgLen)
|
||||
log.Info("invalid MaxMsgLen",log.Uint32("reset", client.MaxMsgLen))
|
||||
}
|
||||
if client.HandshakeTimeout <= 0 {
|
||||
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 {
|
||||
log.SFatal("NewAgent must not be nil")
|
||||
log.Fatal("NewAgent must not be nil")
|
||||
}
|
||||
if client.cons != nil {
|
||||
log.SFatal("client is running")
|
||||
log.Fatal("client is running")
|
||||
}
|
||||
|
||||
if client.MessageType == 0 {
|
||||
@@ -83,7 +83,7 @@ func (client *WSClient) dial() *websocket.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)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (wsConn *WSConn) Close() {
|
||||
|
||||
func (wsConn *WSConn) doWrite(b []byte) {
|
||||
if len(wsConn.writeChan) == cap(wsConn.writeChan) {
|
||||
log.SDebug("close conn: channel full")
|
||||
log.Debug("close conn: channel full")
|
||||
wsConn.doDestroy()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func (handler *WSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
conn, err := handler.upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.SError("upgrade error: ", err.Error())
|
||||
log.Error("upgrade fail",log.String("error",err.Error()))
|
||||
return
|
||||
}
|
||||
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 {
|
||||
handler.mutexConns.Unlock()
|
||||
conn.Close()
|
||||
log.SWarning("too many connections")
|
||||
log.Warning("too many connections")
|
||||
return
|
||||
}
|
||||
handler.conns[conn] = struct{}{}
|
||||
@@ -95,27 +95,27 @@ func (server *WSServer) SetMessageType(messageType int) {
|
||||
func (server *WSServer) Start() {
|
||||
ln, err := net.Listen("tcp", server.Addr)
|
||||
if err != nil {
|
||||
log.SFatal("WSServer Listen fail:", err.Error())
|
||||
log.Fatal("WSServer Listen fail",log.String("error", err.Error()))
|
||||
}
|
||||
|
||||
if server.MaxConnNum <= 0 {
|
||||
server.MaxConnNum = 100
|
||||
log.SRelease("invalid MaxConnNum, reset to ", server.MaxConnNum)
|
||||
log.Info("invalid MaxConnNum", log.Int("reset", server.MaxConnNum))
|
||||
}
|
||||
if server.PendingWriteNum <= 0 {
|
||||
server.PendingWriteNum = 100
|
||||
log.SRelease("invalid PendingWriteNum, reset to ", server.PendingWriteNum)
|
||||
log.Info("invalid PendingWriteNum", log.Int("reset", server.PendingWriteNum))
|
||||
}
|
||||
if server.MaxMsgLen <= 0 {
|
||||
server.MaxMsgLen = 4096
|
||||
log.SRelease("invalid MaxMsgLen, reset to ", server.MaxMsgLen)
|
||||
log.Info("invalid MaxMsgLen", log.Uint32("reset", server.MaxMsgLen))
|
||||
}
|
||||
if server.HTTPTimeout <= 0 {
|
||||
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 {
|
||||
log.SFatal("NewAgent must not be nil")
|
||||
log.Fatal("NewAgent must not be nil")
|
||||
}
|
||||
|
||||
if server.CertFile != "" || server.KeyFile != "" {
|
||||
@@ -126,7 +126,7 @@ func (server *WSServer) Start() {
|
||||
config.Certificates = make([]tls.Certificate, 1)
|
||||
config.Certificates[0], err = tls.LoadX509KeyPair(server.CertFile, server.KeyFile)
|
||||
if err != nil {
|
||||
log.SFatal("LoadX509KeyPair fail:", err.Error())
|
||||
log.Fatal("LoadX509KeyPair fail",log.String("error", err.Error()))
|
||||
}
|
||||
|
||||
ln = tls.NewListener(ln, config)
|
||||
|
||||
185
node/node.go
185
node/node.go
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/duanhf2012/origin/util/buildtime"
|
||||
"github.com/duanhf2012/origin/util/timer"
|
||||
"io"
|
||||
slog "log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
@@ -20,6 +19,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"github.com/duanhf2012/origin/util/sysprocess"
|
||||
)
|
||||
|
||||
var sig chan os.Signal
|
||||
@@ -28,8 +28,12 @@ var preSetupService []service.IService //预安装
|
||||
var profilerInterval time.Duration
|
||||
var bValid bool
|
||||
var configDir = "./config/"
|
||||
var logLevel string = "debug"
|
||||
var logPath string
|
||||
|
||||
const(
|
||||
SingleStop syscall.Signal = 10
|
||||
SignalRetire syscall.Signal = 12
|
||||
)
|
||||
|
||||
type BuildOSType = int8
|
||||
|
||||
const(
|
||||
@@ -39,20 +43,28 @@ const(
|
||||
)
|
||||
|
||||
func init() {
|
||||
sig = make(chan os.Signal, 3)
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.Signal(10))
|
||||
sig = make(chan os.Signal, 4)
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, SingleStop,SignalRetire)
|
||||
|
||||
console.RegisterCommandBool("help", false, "<-help> This help.", usage)
|
||||
console.RegisterCommandString("name", "", "<-name nodeName> Node's name.", setName)
|
||||
console.RegisterCommandString("start", "", "<-start nodeid=nodeid> Run originserver.", startNode)
|
||||
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("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("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)
|
||||
}
|
||||
|
||||
|
||||
func notifyAllServiceRetire(){
|
||||
service.NotifyAllServiceRetire()
|
||||
}
|
||||
|
||||
func usage(val interface{}) error {
|
||||
ret := val.(bool)
|
||||
if ret == false {
|
||||
@@ -144,7 +156,7 @@ func initNode(id int) {
|
||||
nodeId = id
|
||||
err := cluster.GetCluster().Init(GetNodeId(), Setup)
|
||||
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()
|
||||
@@ -168,7 +180,7 @@ func initNode(id int) {
|
||||
}
|
||||
|
||||
if bSetup == false {
|
||||
log.SFatal("Service name "+serviceName+" configuration error")
|
||||
log.Fatal("Service name "+serviceName+" configuration error")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,18 +189,18 @@ func initNode(id int) {
|
||||
}
|
||||
|
||||
func initLog() error {
|
||||
if logPath == "" {
|
||||
if log.LogPath == "" {
|
||||
setLogPath("./log")
|
||||
}
|
||||
|
||||
localnodeinfo := cluster.GetCluster().GetLocalNodeInfo()
|
||||
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 {
|
||||
fmt.Printf("cannot create log file!\n")
|
||||
return err
|
||||
}
|
||||
log.Export(logger)
|
||||
log.SetLogger(logger)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
//1.解析参数
|
||||
param := args.(string)
|
||||
@@ -214,12 +257,12 @@ func stopNode(args interface{}) error {
|
||||
if sParam[0] != "nodeid" {
|
||||
return fmt.Errorf("invalid option %s", param)
|
||||
}
|
||||
nodeId, err := strconv.Atoi(sParam[1])
|
||||
nId, err := strconv.Atoi(sParam[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid option %s", param)
|
||||
}
|
||||
|
||||
processId, err := getRunProcessPid(nodeId)
|
||||
processId, err := getRunProcessPid(nId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,20 +289,43 @@ func startNode(args interface{}) error {
|
||||
if err != nil {
|
||||
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)
|
||||
log.SRelease("Start running server.")
|
||||
//2.初始化node
|
||||
|
||||
//3.初始化node
|
||||
initNode(nodeId)
|
||||
|
||||
//3.运行service
|
||||
//4.运行service
|
||||
service.Start()
|
||||
|
||||
//4.运行集群
|
||||
//5.运行集群
|
||||
cluster.GetCluster().Start()
|
||||
|
||||
//5.记录进程id号
|
||||
writeProcessPid(nodeId)
|
||||
|
||||
|
||||
//6.监听程序退出信号&性能报告
|
||||
bRun := true
|
||||
@@ -267,20 +333,29 @@ func startNode(args interface{}) error {
|
||||
if profilerInterval > 0 {
|
||||
pProfilerTicker = time.NewTicker(profilerInterval)
|
||||
}
|
||||
|
||||
for bRun {
|
||||
select {
|
||||
case <-sig:
|
||||
log.SRelease("receipt stop signal.")
|
||||
bRun = false
|
||||
case s := <-sig:
|
||||
signal := s.(syscall.Signal)
|
||||
if signal == SignalRetire {
|
||||
log.Info("receipt retire signal.")
|
||||
notifyAllServiceRetire()
|
||||
}else {
|
||||
bRun = false
|
||||
log.Info("receipt stop signal.")
|
||||
}
|
||||
case <-pProfilerTicker.C:
|
||||
profiler.Report()
|
||||
}
|
||||
}
|
||||
|
||||
cluster.GetCluster().Stop()
|
||||
//7.退出
|
||||
service.StopAllService()
|
||||
|
||||
log.SRelease("Server is stop.")
|
||||
log.Info("Server is stop.")
|
||||
log.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -304,11 +379,6 @@ func GetConfigDir() string {
|
||||
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) {
|
||||
profilerInterval = interval
|
||||
}
|
||||
@@ -333,9 +403,24 @@ func setLevel(args interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
logLevel = strings.TrimSpace(args.(string))
|
||||
if logLevel != "debug" && logLevel != "release" && logLevel != "warning" && logLevel != "error" && logLevel != "fatal" {
|
||||
return errors.New("unknown level: " + logLevel)
|
||||
strlogLevel := strings.TrimSpace(args.(string))
|
||||
switch strlogLevel {
|
||||
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
|
||||
}
|
||||
@@ -344,18 +429,48 @@ func setLogPath(args interface{}) error {
|
||||
if args == "" {
|
||||
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 {
|
||||
return errors.New("Not found dir " + logPath)
|
||||
return errors.New("Not found dir " + log.LogPath)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = os.Mkdir(logPath, os.ModePerm)
|
||||
err = os.Mkdir(log.LogPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return errors.New("Cannot create dir " + logPath)
|
||||
return errors.New("Cannot create dir " + log.LogPath)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func KillProcess(processId int){
|
||||
err := syscall.Kill(processId,syscall.Signal(10))
|
||||
err := syscall.Kill(processId,SingleStop)
|
||||
if err != nil {
|
||||
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
|
||||
}else{
|
||||
@@ -19,3 +19,12 @@ func KillProcess(processId int){
|
||||
func GetBuildOSType() BuildOSType{
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func KillProcess(processId int){
|
||||
err := syscall.Kill(processId,syscall.Signal(10))
|
||||
err := syscall.Kill(processId,SingleStop)
|
||||
if err != nil {
|
||||
fmt.Printf("kill processid %d is fail:%+v.\n",processId,err)
|
||||
}else{
|
||||
@@ -19,3 +19,12 @@ func KillProcess(processId int){
|
||||
func GetBuildOSType() BuildOSType{
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,28 @@
|
||||
|
||||
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{
|
||||
return Windows
|
||||
}
|
||||
|
||||
func RetireProcess(processId int){
|
||||
fmt.Printf("This command does not support Windows")
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ func DefaultReportFunction(name string,callNum int,costTime time.Duration,record
|
||||
elem = elem.Next()
|
||||
}
|
||||
|
||||
log.SRelease(strReport)
|
||||
log.SInfo("report",strReport)
|
||||
}
|
||||
|
||||
func Report() {
|
||||
|
||||
104
rpc/client.go
104
rpc/client.go
@@ -1,7 +1,6 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"errors"
|
||||
"github.com/duanhf2012/origin/network"
|
||||
"reflect"
|
||||
@@ -9,6 +8,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"github.com/duanhf2012/origin/log"
|
||||
)
|
||||
|
||||
const(
|
||||
@@ -20,7 +20,7 @@ const(
|
||||
|
||||
|
||||
DefaultConnectInterval = 2*time.Second
|
||||
DefaultCheckRpcCallTimeoutInterval = 5*time.Second
|
||||
DefaultCheckRpcCallTimeoutInterval = 1*time.Second
|
||||
DefaultRpcTimeout = 15*time.Second
|
||||
)
|
||||
|
||||
@@ -30,9 +30,9 @@ type IRealClient interface {
|
||||
SetConn(conn *network.TCPConn)
|
||||
Close(waitDone bool)
|
||||
|
||||
AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{}) error
|
||||
Go(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
|
||||
AsyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{},cancelable bool) (CancelRpc,error)
|
||||
Go(timeout time.Duration,rpcHandler IRpcHandler, noReply bool, serviceMethod string, args interface{}, reply interface{}) *Call
|
||||
RawGo(timeout time.Duration,rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call
|
||||
IsConnected() bool
|
||||
|
||||
Run()
|
||||
@@ -44,11 +44,11 @@ type Client struct {
|
||||
nodeId int
|
||||
pendingLock sync.RWMutex
|
||||
startSeq uint64
|
||||
pending map[uint64]*list.Element
|
||||
pendingTimer *list.List
|
||||
pending map[uint64]*Call
|
||||
callRpcTimeout time.Duration
|
||||
maxCheckCallRpcCount int
|
||||
|
||||
callTimerHeap CallTimerHeap
|
||||
IRealClient
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ func (client *Client) NewClientAgent(conn *network.TCPConn) network.Agent {
|
||||
}
|
||||
|
||||
func (bc *Client) makeCallFail(call *Call) {
|
||||
bc.removePending(call.Seq)
|
||||
if call.callback != nil && call.callback.IsValid() {
|
||||
call.rpcHandler.PushRpcResponse(call)
|
||||
} else {
|
||||
@@ -70,54 +69,52 @@ func (bc *Client) makeCallFail(call *Call) {
|
||||
func (bc *Client) checkRpcCallTimeout() {
|
||||
for{
|
||||
time.Sleep(DefaultCheckRpcCallTimeoutInterval)
|
||||
now := time.Now()
|
||||
|
||||
for i := 0; i < bc.maxCheckCallRpcCount; i++ {
|
||||
bc.pendingLock.Lock()
|
||||
if bc.pendingTimer == nil {
|
||||
|
||||
callSeq := bc.callTimerHeap.PopTimeout()
|
||||
if callSeq == 0 {
|
||||
bc.pendingLock.Unlock()
|
||||
break
|
||||
}
|
||||
|
||||
pElem := bc.pendingTimer.Front()
|
||||
if pElem == 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)
|
||||
pCall := bc.pending[callSeq]
|
||||
if pCall == nil {
|
||||
bc.pendingLock.Unlock()
|
||||
log.Error("call seq is not find",log.Uint64("seq", callSeq))
|
||||
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()
|
||||
break
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) InitPending() {
|
||||
client.pendingLock.Lock()
|
||||
if client.pending != nil {
|
||||
for _, v := range client.pending {
|
||||
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.callTimerHeap.Init()
|
||||
client.pending = make(map[uint64]*Call,4096)
|
||||
client.pendingLock.Unlock()
|
||||
}
|
||||
|
||||
|
||||
func (bc *Client) AddPending(call *Call) {
|
||||
bc.pendingLock.Lock()
|
||||
call.callTime = time.Now()
|
||||
elemTimer := bc.pendingTimer.PushBack(call)
|
||||
bc.pending[call.Seq] = elemTimer //如果下面发送失败,将会一一直存在这里
|
||||
|
||||
if call.Seq == 0 {
|
||||
bc.pendingLock.Unlock()
|
||||
log.Stack("call is error.")
|
||||
return
|
||||
}
|
||||
|
||||
bc.pending[call.Seq] = call
|
||||
bc.callTimerHeap.AddTimer(call.Seq,call.TimeOut)
|
||||
|
||||
bc.pendingLock.Unlock()
|
||||
}
|
||||
|
||||
@@ -136,30 +133,45 @@ func (bc *Client) removePending(seq uint64) *Call {
|
||||
if ok == false {
|
||||
return nil
|
||||
}
|
||||
call := v.Value.(*Call)
|
||||
bc.pendingTimer.Remove(v)
|
||||
|
||||
bc.callTimerHeap.Cancel(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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bc.pendingLock.Lock()
|
||||
v, ok := bc.pending[seq]
|
||||
if ok == false {
|
||||
bc.pendingLock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
pCall := v.Value.(*Call)
|
||||
pCall = bc.pending[seq]
|
||||
bc.pendingLock.Unlock()
|
||||
|
||||
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 {
|
||||
return atomic.AddUint64(&bc.startSeq, 1)
|
||||
}
|
||||
|
||||
102
rpc/compressor.go
Normal file
102
rpc/compressor.go
Normal 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
@@ -1,6 +1,6 @@
|
||||
syntax = "proto3";
|
||||
package rpc;
|
||||
option go_package = "./rpc";
|
||||
option go_package = ".;rpc";
|
||||
|
||||
message NodeInfo{
|
||||
int32 NodeId = 1;
|
||||
@@ -8,7 +8,8 @@ message NodeInfo{
|
||||
string ListenAddr = 3;
|
||||
uint32 MaxRpcParamLen = 4;
|
||||
bool Private = 5;
|
||||
repeated string PublicServiceList = 6;
|
||||
bool Retire = 6;
|
||||
repeated string PublicServiceList = 7;
|
||||
}
|
||||
|
||||
//Client->Master
|
||||
@@ -24,6 +25,12 @@ message SubscribeDiscoverNotify{
|
||||
repeated NodeInfo nodeInfo = 4;
|
||||
}
|
||||
|
||||
|
||||
//Client->Master
|
||||
message NodeRetireReq{
|
||||
NodeInfo nodeInfo = 1;
|
||||
}
|
||||
|
||||
//Master->Client
|
||||
message Empty{
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
)
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
//本结点的Client
|
||||
@@ -36,13 +37,13 @@ func (lc *LClient) SetConn(conn *network.TCPConn){
|
||||
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()()
|
||||
//判断是否是同一服务
|
||||
findIndex := strings.Index(serviceMethod, ".")
|
||||
if findIndex == -1 {
|
||||
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.DoError(sErr)
|
||||
|
||||
@@ -65,19 +66,20 @@ func (lc *LClient) Go(rpcHandler IRpcHandler,noReply bool, serviceMethod string,
|
||||
}
|
||||
|
||||
//其他的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()()
|
||||
|
||||
call := MakeCall()
|
||||
call.ServiceMethod = serviceName
|
||||
call.Reply = reply
|
||||
|
||||
|
||||
//服务自我调用
|
||||
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)
|
||||
call.Err = err
|
||||
call.done <- call
|
||||
@@ -86,11 +88,11 @@ func (rc *LClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
|
||||
}
|
||||
|
||||
//其他的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()()
|
||||
|
||||
//判断是否是同一服务
|
||||
@@ -98,23 +100,23 @@ func (lc *LClient) AsyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
|
||||
if findIndex == -1 {
|
||||
err := errors.New("Call serviceMethod " + serviceMethod + " is error!")
|
||||
callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
|
||||
log.SError(err.Error())
|
||||
return nil
|
||||
log.Error("serviceMethod format is error",log.String("error",err.Error()))
|
||||
return emptyCancelRpc,nil
|
||||
}
|
||||
|
||||
serviceName := serviceMethod[:findIndex]
|
||||
//调用自己rpcHandler处理器
|
||||
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的处理器
|
||||
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 {
|
||||
callback.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
|
||||
}
|
||||
|
||||
return nil
|
||||
return calcelRpc,nil
|
||||
}
|
||||
|
||||
func NewLClient(nodeId int) *Client{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
106
rpc/pbprocessor.go
Normal file
106
rpc/pbprocessor.go
Normal 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
263
rpc/protorpc.pb.go
Normal 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
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
syntax = "proto3";
|
||||
package rpc;
|
||||
option go_package = "./rpc";
|
||||
option go_package = ".;rpc";
|
||||
|
||||
message GoGoPBRpcRequestData{
|
||||
message PBRpcRequestData{
|
||||
uint64 Seq = 1;
|
||||
uint32 RpcMethodId = 2;
|
||||
string ServiceMethod = 3;
|
||||
@@ -10,7 +10,7 @@ message GoGoPBRpcRequestData{
|
||||
bytes InParam = 5;
|
||||
}
|
||||
|
||||
message GoGoPBRpcResponseData{
|
||||
message PBRpcResponseData{
|
||||
uint64 Seq = 1;
|
||||
string Error = 2;
|
||||
bytes Reply = 3;
|
||||
6224
rpc/rank.pb.go
6224
rpc/rank.pb.go
File diff suppressed because it is too large
Load Diff
142
rpc/rclient.go
142
rpc/rclient.go
@@ -9,10 +9,12 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
//跨结点连接的Client
|
||||
type RClient struct {
|
||||
compressBytesLen int
|
||||
selfClient *Client
|
||||
network.TCPClient
|
||||
conn *network.TCPConn
|
||||
@@ -40,25 +42,25 @@ func (rc *RClient) SetConn(conn *network.TCPConn){
|
||||
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)
|
||||
InParam, err := processor.Marshal(args)
|
||||
if err != nil {
|
||||
log.SError(err.Error())
|
||||
log.Error("Marshal is fail",log.ErrorAttr("error",err))
|
||||
call := MakeCall()
|
||||
call.DoError(err)
|
||||
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(rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call {
|
||||
func (rc *RClient) RawGo(timeout time.Duration,rpcHandler IRpcHandler,processor IRpcProcessor, noReply bool, rpcMethodId uint32, serviceMethod string, rawArgs []byte, reply interface{}) *Call {
|
||||
call := MakeCall()
|
||||
call.ServiceMethod = serviceMethod
|
||||
call.Reply = reply
|
||||
call.Seq = rc.selfClient.generateSeq()
|
||||
call.TimeOut = timeout
|
||||
|
||||
request := MakeRpcRequest(processor, call.Seq, rpcMethodId, serviceMethod, noReply, rawArgs)
|
||||
bytes, err := processor.Marshal(request.RpcRequestData)
|
||||
@@ -66,7 +68,7 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
|
||||
|
||||
if err != nil {
|
||||
call.Seq = 0
|
||||
log.SError(err.Error())
|
||||
log.Error("marshal is fail",log.String("error",err.Error()))
|
||||
call.DoError(err)
|
||||
return call
|
||||
}
|
||||
@@ -75,21 +77,39 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
|
||||
if conn == nil || conn.IsConnected()==false {
|
||||
call.Seq = 0
|
||||
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)
|
||||
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 {
|
||||
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 {
|
||||
rc.selfClient.RemovePending(call.Seq)
|
||||
|
||||
log.SError(err.Error())
|
||||
|
||||
log.Error("WiteMsg is fail",log.ErrorAttr("error",err))
|
||||
call.Seq = 0
|
||||
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 {
|
||||
err := rc.asyncCall(rpcHandler, serviceMethod, callback, args, replyParam)
|
||||
func (rc *RClient) AsyncCall(timeout time.Duration,rpcHandler IRpcHandler, serviceMethod string, callback reflect.Value, args interface{}, replyParam interface{},cancelable bool) (CancelRpc,error) {
|
||||
cancelRpc,err := rc.asyncCall(timeout,rpcHandler, serviceMethod, callback, args, replyParam,cancelable)
|
||||
if err != nil {
|
||||
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)
|
||||
InParam, herr := processor.Marshal(args)
|
||||
if herr != nil {
|
||||
return herr
|
||||
return emptyCancelRpc,herr
|
||||
}
|
||||
|
||||
seq := rc.selfClient.generateSeq()
|
||||
@@ -119,12 +139,27 @@ func (rc *RClient) asyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
|
||||
bytes, err := processor.Marshal(request.RpcRequestData)
|
||||
ReleaseRpcRequest(request)
|
||||
if err != nil {
|
||||
return err
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
conn := rc.GetConn()
|
||||
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()
|
||||
@@ -133,16 +168,25 @@ func (rc *RClient) asyncCall(rpcHandler IRpcHandler, serviceMethod string, callb
|
||||
call.rpcHandler = rpcHandler
|
||||
call.ServiceMethod = serviceMethod
|
||||
call.Seq = seq
|
||||
call.TimeOut = timeout
|
||||
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 {
|
||||
rc.selfClient.RemovePending(call.Seq)
|
||||
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() {
|
||||
@@ -151,7 +195,7 @@ func (rc *RClient) Run() {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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 {
|
||||
bytes, err := rc.conn.ReadMsg()
|
||||
if err != nil {
|
||||
log.SError("rpcClient ", rc.Addr, " ReadMsg error:", err.Error())
|
||||
log.Error("rclient read msg is failed",log.ErrorAttr("error",err))
|
||||
return
|
||||
}
|
||||
|
||||
processor := GetProcessor(bytes[0])
|
||||
bCompress := (bytes[0]>>7) > 0
|
||||
processor := GetProcessor(bytes[0]&0x7f)
|
||||
if processor == nil {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -174,23 +219,42 @@ func (rc *RClient) Run() {
|
||||
response := RpcResponse{}
|
||||
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)
|
||||
if err != nil {
|
||||
processor.ReleaseRpcResponse(response.RpcResponseData)
|
||||
log.SError("rpcClient Unmarshal head error:", err.Error())
|
||||
log.Error("rpcClient Unmarshal head error",log.ErrorAttr("error",err))
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
v := rc.selfClient.RemovePending(response.RpcResponseData.GetSeq())
|
||||
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 {
|
||||
v.Err = nil
|
||||
if len(response.RpcResponseData.GetReply()) > 0 {
|
||||
err = processor.Unmarshal(response.RpcResponseData.GetReply(), v.Reply)
|
||||
if err != nil {
|
||||
log.SError("rpcClient Unmarshal body error:", err.Error())
|
||||
log.Error("rpcClient Unmarshal body failed",log.ErrorAttr("error",err))
|
||||
v.Err = err
|
||||
}
|
||||
}
|
||||
@@ -214,14 +278,14 @@ func (rc *RClient) OnClose() {
|
||||
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.clientId = atomic.AddUint32(&clientSeq, 1)
|
||||
client.nodeId = nodeId
|
||||
client.maxCheckCallRpcCount = DefaultMaxCheckCallRpcCount
|
||||
client.callRpcTimeout = DefaultRpcTimeout
|
||||
|
||||
c:= &RClient{}
|
||||
c.compressBytesLen = compressBytesLen
|
||||
c.selfClient = client
|
||||
c.Addr = addr
|
||||
c.ConnectInterval = DefaultConnectInterval
|
||||
@@ -251,18 +315,6 @@ func NewRClient(nodeId int, addr string, maxRpcParamLen uint32,triggerRpcConnEve
|
||||
|
||||
func (rc *RClient) Close(waitDone bool) {
|
||||
rc.TCPClient.Close(waitDone)
|
||||
|
||||
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()
|
||||
rc.selfClient.cleanPending()
|
||||
}
|
||||
|
||||
|
||||
13
rpc/rpc.go
13
rpc/rpc.go
@@ -68,7 +68,16 @@ type Call struct {
|
||||
connId int
|
||||
callback *reflect.Value
|
||||
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{
|
||||
@@ -124,6 +133,8 @@ func (call *Call) Clear() *Call{
|
||||
call.connId = 0
|
||||
call.callback = nil
|
||||
call.rpcHandler = nil
|
||||
call.TimeOut = 0
|
||||
|
||||
return call
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,12 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
"time"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -72,9 +73,12 @@ type INodeListener interface {
|
||||
|
||||
type IDiscoveryServiceListener interface {
|
||||
OnDiscoveryService(nodeId int, serviceName []string)
|
||||
OnUnDiscoveryService(nodeId int, serviceName []string)
|
||||
OnUnDiscoveryService(nodeId int)
|
||||
}
|
||||
|
||||
type CancelRpc func()
|
||||
func emptyCancelRpc(){}
|
||||
|
||||
type IRpcHandler interface {
|
||||
IRpcHandlerChannel
|
||||
GetName() string
|
||||
@@ -83,11 +87,18 @@ type IRpcHandler interface {
|
||||
HandlerRpcRequest(request *RpcRequest)
|
||||
HandlerRpcResponseCB(call *Call)
|
||||
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
|
||||
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
|
||||
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
|
||||
RawGoNode(rpcProcessorType RpcProcessorType, nodeId int, rpcMethodId uint32, serviceName string, rawArgs []byte) error
|
||||
CastGo(serviceMethod string, args interface{}) error
|
||||
@@ -204,7 +215,7 @@ func (handler *RpcHandler) HandlerRpcResponseCB(call *Call) {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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)
|
||||
l := runtime.Stack(buf, false)
|
||||
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")
|
||||
if request.requestHandle != nil {
|
||||
request.requestHandle(nil, rpcErr)
|
||||
@@ -239,12 +250,12 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
|
||||
if rawRpcId > 0 {
|
||||
v, ok := handler.mapRawFunctions[rawRpcId]
|
||||
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
|
||||
}
|
||||
rawData,ok := request.inParam.([]byte)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -256,7 +267,7 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
|
||||
v, ok := handler.mapFunctions[request.RpcRequestData.GetServiceMethod()]
|
||||
if ok == false {
|
||||
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 {
|
||||
request.requestHandle(nil, RpcError(err))
|
||||
}
|
||||
@@ -287,7 +298,7 @@ func (handler *RpcHandler) HandlerRpcRequest(request *RpcRequest) {
|
||||
paramList = append(paramList, oParam) //输出参数
|
||||
} else if request.requestHandle != nil && v.hasResponder == false { //调用方有返回值,但被调用函数没有返回参数
|
||||
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))
|
||||
return
|
||||
}
|
||||
@@ -309,7 +320,7 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
|
||||
v, ok := handler.mapFunctions[ServiceMethod]
|
||||
if ok == false {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -323,7 +334,8 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
|
||||
pCall.callback = &callBack
|
||||
pCall.Seq = client.generateSeq()
|
||||
callSeq = pCall.Seq
|
||||
|
||||
pCall.TimeOut = DefaultRpcTimeout
|
||||
pCall.ServiceMethod = ServiceMethod
|
||||
client.AddPending(pCall)
|
||||
|
||||
//有返回值时
|
||||
@@ -332,7 +344,7 @@ func (handler *RpcHandler) CallMethod(client *Client,ServiceMethod string, param
|
||||
hander :=func(Returns interface{}, Err RpcError) {
|
||||
rpcCall := client.RemovePending(callSeq)
|
||||
if rpcCall == nil {
|
||||
log.SError("cannot find call seq ",callSeq)
|
||||
log.Error("cannot find call seq",log.Uint64("seq",callSeq))
|
||||
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 {
|
||||
var pClientList [maxClusterNode]*Client
|
||||
err, count := handler.funcRpcClient(nodeId, serviceMethod, pClientList[:])
|
||||
err, count := handler.funcRpcClient(nodeId, serviceMethod,false, pClientList[:])
|
||||
if count == 0 {
|
||||
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 {
|
||||
log.SError("Can not find ", serviceMethod)
|
||||
log.Error("cannot find serviceMethod",log.String("serviceMethod",serviceMethod))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
//2.rpcClient调用
|
||||
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 {
|
||||
err = pCall.Err
|
||||
}
|
||||
@@ -444,23 +456,23 @@ func (handler *RpcHandler) goRpc(processor IRpcProcessor, bCast bool, nodeId int
|
||||
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
|
||||
err, count := handler.funcRpcClient(nodeId, serviceMethod, pClientList[:])
|
||||
err, count := handler.funcRpcClient(nodeId, serviceMethod,false, pClientList[:])
|
||||
if err != nil {
|
||||
log.SError("Call serviceMethod is error:", err.Error())
|
||||
log.Error("Call serviceMethod is failed",log.ErrorAttr("error",err))
|
||||
return err
|
||||
} else if count <= 0 {
|
||||
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
|
||||
} 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")
|
||||
}
|
||||
|
||||
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
|
||||
pClient.RemovePending(pCall.Seq)
|
||||
@@ -468,29 +480,29 @@ func (handler *RpcHandler) callRpc(nodeId int, serviceMethod string, args interf
|
||||
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)
|
||||
if fVal.Kind() != reflect.Func {
|
||||
err := errors.New("call " + serviceMethod + " input callback param is error!")
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
log.Error("input callback param is error",log.String("serviceMethod",serviceMethod))
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
if fVal.Type().NumIn() != 2 {
|
||||
err := errors.New("call " + serviceMethod + " callback param function is error!")
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
log.Error("callback param function is error",log.String("serviceMethod",serviceMethod))
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
if fVal.Type().In(0).Kind() != reflect.Ptr || fVal.Type().In(1).String() != "error" {
|
||||
err := errors.New("call " + serviceMethod + " callback param function is error!")
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
log.Error("callback param function is error",log.String("serviceMethod",serviceMethod))
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
reply := reflect.New(fVal.Type().In(0).Elem()).Interface()
|
||||
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 err == nil {
|
||||
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)})
|
||||
log.SError("Call serviceMethod is error:", err.Error())
|
||||
return nil
|
||||
log.Error("cannot find serviceMethod from node",log.String("serviceMethod",serviceMethod),log.Int("nodeId",nodeId))
|
||||
return emptyCancelRpc,nil
|
||||
}
|
||||
|
||||
if count > 1 {
|
||||
err := errors.New("cannot call more then 1 node")
|
||||
fVal.Call([]reflect.Value{reflect.ValueOf(reply), reflect.ValueOf(err)})
|
||||
log.SError(err.Error())
|
||||
return nil
|
||||
log.Error("cannot call more then 1 node",log.String("serviceMethod",serviceMethod))
|
||||
return emptyCancelRpc,nil
|
||||
}
|
||||
|
||||
//2.rpcClient调用
|
||||
//如果调用本结点服务
|
||||
pClient := pClientList[0]
|
||||
pClient.AsyncCall(handler.rpcHandler, serviceMethod, fVal, args, reply)
|
||||
|
||||
|
||||
return nil
|
||||
return pClientList[0].AsyncCall(timeout,handler.rpcHandler, serviceMethod, fVal, args, reply,false)
|
||||
}
|
||||
|
||||
func (handler *RpcHandler) GetName() string {
|
||||
@@ -528,12 +536,29 @@ func (handler *RpcHandler) IsSingleCoroutine() bool {
|
||||
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 {
|
||||
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 {
|
||||
return handler.callRpc(0, serviceMethod, args, reply)
|
||||
return handler.callRpc(DefaultRpcTimeout,0, serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
@@ -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 {
|
||||
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 {
|
||||
log.SError("Call serviceMethod is error:", err.Error())
|
||||
log.Error("call serviceMethod is failed",log.ErrorAttr("error",err))
|
||||
return err
|
||||
}
|
||||
if count > 1 {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -573,7 +600,7 @@ func (handler *RpcHandler) RawGoNode(rpcProcessorType RpcProcessorType, nodeId i
|
||||
//如果调用本结点服务
|
||||
for i := 0; i < count; i++ {
|
||||
//跨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 {
|
||||
err = pCall.Err
|
||||
}
|
||||
|
||||
89
rpc/rpctimer.go
Normal file
89
rpc/rpctimer.go
Normal 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)
|
||||
}
|
||||
|
||||
142
rpc/server.go
142
rpc/server.go
@@ -10,16 +10,17 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type RpcProcessorType uint8
|
||||
|
||||
const (
|
||||
RpcProcessorJson RpcProcessorType = 0
|
||||
RpcProcessorGoGoPB RpcProcessorType = 1
|
||||
RpcProcessorPB RpcProcessorType = 1
|
||||
)
|
||||
|
||||
var arrayProcessor = []IRpcProcessor{&JsonProcessor{}, &GoGoPBProcessor{}}
|
||||
var arrayProcessor = []IRpcProcessor{&JsonProcessor{}, &PBProcessor{}}
|
||||
var arrayProcessorLen uint8 = 2
|
||||
var LittleEndian bool
|
||||
|
||||
@@ -27,6 +28,8 @@ type Server struct {
|
||||
functions map[interface{}]interface{}
|
||||
rpcHandleFinder RpcHandleFinder
|
||||
rpcServer *network.TCPServer
|
||||
|
||||
compressBytesLen int
|
||||
}
|
||||
|
||||
type RpcAgent struct {
|
||||
@@ -64,14 +67,15 @@ func (server *Server) Init(rpcHandleFinder RpcHandleFinder) {
|
||||
|
||||
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, ":")
|
||||
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.MinMsgLen = 2
|
||||
server.compressBytesLen = compressBytesLen
|
||||
if maxRpcParamLen > 0 {
|
||||
server.rpcServer.MaxMsgLen = maxRpcParamLen
|
||||
} else {
|
||||
@@ -108,38 +112,84 @@ func (agent *RpcAgent) WriteResponse(processor IRpcProcessor, serviceMethod stri
|
||||
defer processor.ReleaseRpcResponse(rpcResponse.RpcResponseData)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
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() {
|
||||
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 {
|
||||
data, err := agent.conn.ReadMsg()
|
||||
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
|
||||
break
|
||||
}
|
||||
|
||||
processor := GetProcessor(data[0])
|
||||
bCompress := (data[0]>>7) > 0
|
||||
processor := GetProcessor(data[0]&0x7f)
|
||||
if processor == nil {
|
||||
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
|
||||
}
|
||||
|
||||
//解析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)
|
||||
err = processor.Unmarshal(data[1:], req.RpcRequestData)
|
||||
err = processor.Unmarshal(byteData, req.RpcRequestData)
|
||||
if cap(compressBuff) > 0 {
|
||||
compressor.UnCompressBufferCollection(compressBuff)
|
||||
}
|
||||
agent.conn.ReleaseReadMsg(data)
|
||||
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 {
|
||||
rpcError := RpcError(err.Error())
|
||||
if req.RpcRequestData.IsNoReply() == false {
|
||||
@@ -161,7 +211,7 @@ func (agent *RpcAgent) Run() {
|
||||
agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError)
|
||||
}
|
||||
ReleaseRpcRequest(req)
|
||||
log.SError("rpc request req.ServiceMethod is error")
|
||||
log.Error("rpc request req.ServiceMethod is error")
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -171,8 +221,7 @@ func (agent *RpcAgent) Run() {
|
||||
if req.RpcRequestData.IsNoReply() == false {
|
||||
agent.WriteResponse(processor, req.RpcRequestData.GetServiceMethod(), req.RpcRequestData.GetSeq(), nil, rpcError)
|
||||
}
|
||||
|
||||
log.SError("service method ", req.RpcRequestData.GetServiceMethod(), " not config!")
|
||||
log.Error("serviceMethod not config",log.String("serviceMethod",req.RpcRequestData.GetServiceMethod()))
|
||||
ReleaseRpcRequest(req)
|
||||
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())
|
||||
if err != nil {
|
||||
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 {
|
||||
req.requestHandle(nil, RpcError(rErr))
|
||||
} else {
|
||||
ReleaseRpcRequest(req)
|
||||
}
|
||||
log.SError(rErr)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -241,23 +291,23 @@ func (server *Server) myselfRpcHandlerGo(client *Client,handlerName string, serv
|
||||
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
|
||||
if rpcHandler == nil {
|
||||
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 rpcHandler.CallMethod(client,serviceMethod, args,callBack, reply)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Client, noReply bool, handlerName string, rpcMethodId uint32, serviceMethod string, args interface{}, reply interface{}, rawArgs []byte) *Call {
|
||||
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 {
|
||||
pCall := MakeCall()
|
||||
pCall.Seq = client.generateSeq()
|
||||
pCall.TimeOut = timeout
|
||||
pCall.ServiceMethod = serviceMethod
|
||||
|
||||
rpcHandler := server.rpcHandleFinder.FindRpcHandler(handlerName)
|
||||
if rpcHandler == nil {
|
||||
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.DoError(err)
|
||||
|
||||
@@ -274,7 +324,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
iParam,err = processor.Clone(args)
|
||||
if err != nil {
|
||||
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.DoError(sErr)
|
||||
|
||||
@@ -289,7 +339,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
var err error
|
||||
req.inParam, err = rpcHandler.UnmarshalInParam(processor, serviceMethod, rpcMethodId, rawArgs)
|
||||
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.DoError(err)
|
||||
ReleaseRpcRequest(req)
|
||||
@@ -305,12 +355,12 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
byteReturns, err := req.rpcProcessor.Marshal(Returns)
|
||||
if err != nil {
|
||||
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{
|
||||
err = req.rpcProcessor.Unmarshal(byteReturns, reply)
|
||||
if err != nil {
|
||||
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)
|
||||
v := client.RemovePending(callSeq)
|
||||
if v == nil {
|
||||
log.SError("rpcClient cannot find seq ",callSeq, " in pending")
|
||||
|
||||
log.Error("rpcClient cannot find seq",log.Uint64("seq",callSeq))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -327,7 +376,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
v.Err = nil
|
||||
v.DoOK()
|
||||
} else {
|
||||
log.SError(Err.Error())
|
||||
log.Error(Err.Error())
|
||||
v.DoError(Err)
|
||||
}
|
||||
}
|
||||
@@ -335,7 +384,7 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
|
||||
err := rpcHandler.PushRpcRequest(req)
|
||||
if err != nil {
|
||||
log.SError(err.Error())
|
||||
log.Error(err.Error())
|
||||
pCall.DoError(err)
|
||||
ReleaseRpcRequest(req)
|
||||
}
|
||||
@@ -343,53 +392,57 @@ func (server *Server) selfNodeRpcHandlerGo(processor IRpcProcessor, client *Clie
|
||||
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)
|
||||
if rpcHandler == nil {
|
||||
err := errors.New("service method " + serviceMethod + " not config!")
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
log.Error(err.Error())
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
_, processor := GetProcessorType(args)
|
||||
iParam,err := processor.Clone(args)
|
||||
if err != nil {
|
||||
errM := errors.New("RpcHandler " + handlerName + "."+serviceMethod+" deep copy inParam is error:" + err.Error())
|
||||
log.SError(errM.Error())
|
||||
return errM
|
||||
log.Error(errM.Error())
|
||||
return emptyCancelRpc,errM
|
||||
}
|
||||
|
||||
req := MakeRpcRequest(processor, 0, 0, serviceMethod, noReply, nil)
|
||||
req.inParam = iParam
|
||||
req.localReply = reply
|
||||
|
||||
cancelRpc := emptyCancelRpc
|
||||
var callSeq uint64
|
||||
if noReply == false {
|
||||
callSeq := client.generateSeq()
|
||||
callSeq = client.generateSeq()
|
||||
pCall := MakeCall()
|
||||
pCall.Seq = callSeq
|
||||
pCall.rpcHandler = callerRpcHandler
|
||||
pCall.callback = &callback
|
||||
pCall.Reply = reply
|
||||
pCall.ServiceMethod = serviceMethod
|
||||
pCall.TimeOut = timeout
|
||||
client.AddPending(pCall)
|
||||
rpcCancel := RpcCancel{CallSeq: callSeq,Cli: client}
|
||||
cancelRpc = rpcCancel.CancelRpc
|
||||
|
||||
req.requestHandle = func(Returns interface{}, Err RpcError) {
|
||||
v := client.RemovePending(callSeq)
|
||||
if v == nil {
|
||||
log.SError("rpcClient cannot find seq ", pCall.Seq, " in pending")
|
||||
//ReleaseCall(pCall)
|
||||
ReleaseRpcRequest(req)
|
||||
return
|
||||
}
|
||||
if len(Err) == 0 {
|
||||
pCall.Err = nil
|
||||
v.Err = nil
|
||||
} else {
|
||||
pCall.Err = Err
|
||||
v.Err = Err
|
||||
}
|
||||
|
||||
if Returns != nil {
|
||||
pCall.Reply = Returns
|
||||
v.Reply = Returns
|
||||
}
|
||||
pCall.rpcHandler.PushRpcResponse(pCall)
|
||||
v.rpcHandler.PushRpcResponse(v)
|
||||
ReleaseRpcRequest(req)
|
||||
}
|
||||
}
|
||||
@@ -397,8 +450,11 @@ func (server *Server) selfNodeRpcHandlerAsyncGo(client *Client, callerRpcHandler
|
||||
err = rpcHandler.PushRpcRequest(req)
|
||||
if err != nil {
|
||||
ReleaseRpcRequest(req)
|
||||
return err
|
||||
if callSeq > 0 {
|
||||
client.RemovePending(callSeq)
|
||||
}
|
||||
return emptyCancelRpc,err
|
||||
}
|
||||
|
||||
return nil
|
||||
return cancelRpc,nil
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func (m *Module) AddModule(module IModule) (uint32, error) {
|
||||
m.child[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
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ func (m *Module) ReleaseModule(moduleId uint32) {
|
||||
|
||||
pModule.self.OnRelease()
|
||||
pModule.GetEventHandler().Destroy()
|
||||
log.SDebug("Release module ", pModule.GetModuleName())
|
||||
log.Debug("Release module "+ pModule.GetModuleName())
|
||||
for pTimer := range pModule.mapActiveTimer {
|
||||
pTimer.Cancel()
|
||||
}
|
||||
@@ -278,18 +278,18 @@ func (m *Module) SafeNewTicker(tickerId *uint64, d time.Duration, AdditionData i
|
||||
|
||||
func (m *Module) CancelTimerId(timerId *uint64) bool {
|
||||
if timerId==nil || *timerId == 0 {
|
||||
log.SWarning("timerId is invalid")
|
||||
log.Warning("timerId is invalid")
|
||||
return false
|
||||
}
|
||||
|
||||
if m.mapActiveIdTimer == nil {
|
||||
log.SError("mapActiveIdTimer is nil")
|
||||
log.Error("mapActiveIdTimer is nil")
|
||||
return false
|
||||
}
|
||||
|
||||
t, ok := m.mapActiveIdTimer[*timerId]
|
||||
if ok == false {
|
||||
log.SStack("cannot find timer id ", timerId)
|
||||
log.Stack("cannot find timer id ", log.Uint64("timerId",*timerId))
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ type IService interface {
|
||||
OnSetup(iService IService)
|
||||
OnInit() error
|
||||
OnStart()
|
||||
OnRetire()
|
||||
OnRelease()
|
||||
|
||||
SetName(serviceName string)
|
||||
@@ -40,6 +41,9 @@ type IService interface {
|
||||
|
||||
SetEventChannelNum(num int)
|
||||
OpenProfiler()
|
||||
|
||||
SetRetire() //设置服务退休状态
|
||||
IsRetire() bool //服务是否退休
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
@@ -51,6 +55,7 @@ type Service struct {
|
||||
serviceCfg interface{}
|
||||
goroutineNum int32
|
||||
startStatus bool
|
||||
retire int32
|
||||
eventProcessor event.IEventProcessor
|
||||
profiler *profiler.Profiler //性能分析器
|
||||
nodeEventLister rpc.INodeListener
|
||||
@@ -93,10 +98,23 @@ func (s *Service) OnSetup(iService IService){
|
||||
func (s *Service) OpenProfiler() {
|
||||
s.profiler = profiler.RegProfiler(s.GetName())
|
||||
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{}) {
|
||||
s.closeSig = make(chan struct{})
|
||||
s.dispatcher =timer.NewDispatcher(timerDispatcherLen)
|
||||
@@ -128,7 +146,7 @@ func (s *Service) Start() {
|
||||
s.wg.Add(1)
|
||||
waitRun.Add(1)
|
||||
go func(){
|
||||
log.SRelease(s.GetName()," service is running",)
|
||||
log.Info(s.GetName()+" service is running",)
|
||||
waitRun.Done()
|
||||
s.Run()
|
||||
}()
|
||||
@@ -155,15 +173,18 @@ func (s *Service) Run() {
|
||||
concurrent.DoCallback(cb)
|
||||
case ev := <- s.chanEvent:
|
||||
switch ev.GetEventType() {
|
||||
case event.Sys_Event_Retire:
|
||||
log.Info("service OnRetire",log.String("servceName",s.GetName()))
|
||||
s.self.(IService).OnRetire()
|
||||
case event.ServiceRpcRequestEvent:
|
||||
cEvent,ok := ev.(*event.Event)
|
||||
if ok == false {
|
||||
log.SError("Type event conversion error")
|
||||
log.Error("Type event conversion error")
|
||||
break
|
||||
}
|
||||
rpcRequest,ok := cEvent.Data.(*rpc.RpcRequest)
|
||||
if ok == false {
|
||||
log.SError("Type *rpc.RpcRequest conversion error")
|
||||
log.Error("Type *rpc.RpcRequest conversion error")
|
||||
break
|
||||
}
|
||||
if s.profiler!=nil {
|
||||
@@ -179,12 +200,12 @@ func (s *Service) Run() {
|
||||
case event.ServiceRpcResponseEvent:
|
||||
cEvent,ok := ev.(*event.Event)
|
||||
if ok == false {
|
||||
log.SError("Type event conversion error")
|
||||
log.Error("Type event conversion error")
|
||||
break
|
||||
}
|
||||
rpcResponseCB,ok := cEvent.Data.(*rpc.Call)
|
||||
if ok == false {
|
||||
log.SError("Type *rpc.Call conversion error")
|
||||
log.Error("Type *rpc.Call conversion error")
|
||||
break
|
||||
}
|
||||
if s.profiler!=nil {
|
||||
@@ -242,7 +263,7 @@ func (s *Service) Release(){
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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(){
|
||||
log.SRelease("stop ",s.GetName()," service ")
|
||||
log.Info("stop "+s.GetName()+" service ")
|
||||
close(s.closeSig)
|
||||
s.wg.Wait()
|
||||
log.SRelease(s.GetName()," service has been stopped")
|
||||
log.Info(s.GetName()+" service has been stopped")
|
||||
}
|
||||
|
||||
func (s *Service) GetServiceCfg()interface{}{
|
||||
@@ -304,7 +325,7 @@ func (s *Service) OnDiscoverServiceEvent(ev event.IEvent){
|
||||
if event.IsDiscovery {
|
||||
s.discoveryServiceLister.OnDiscoveryService(event.NodeId,event.ServiceName)
|
||||
}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{
|
||||
if len(s.chanEvent) >= maxServiceEventChannelNum {
|
||||
err := errors.New("The event channel in the service is full")
|
||||
log.SError(err.Error())
|
||||
log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -380,10 +401,13 @@ func (s *Service) SetEventChannelNum(num int){
|
||||
func (s *Service) SetGoRoutineNum(goroutineNum int32) bool {
|
||||
//已经开始状态不允许修改协程数量,打开性能分析器不允许开多线程
|
||||
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
|
||||
}
|
||||
|
||||
s.goroutineNum = goroutineNum
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Service) OnRetire(){
|
||||
}
|
||||
@@ -60,3 +60,9 @@ func StopAllService(){
|
||||
setupServiceList[i].Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func NotifyAllServiceRetire(){
|
||||
for i := len(setupServiceList) - 1; i >= 0; i-- {
|
||||
setupServiceList[i].SetRetire()
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,15 @@ func (slf *SyncHttpResponse) Get(timeoutMs int) HttpResponse {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *HttpClientModule) Init(maxpool int, proxyUrl string) {
|
||||
func (m *HttpClientModule) InitHttpClient(transport http.RoundTripper,timeout time.Duration,checkRedirect func(req *http.Request, via []*http.Request) error){
|
||||
m.client = &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: timeout,
|
||||
CheckRedirect: checkRedirect,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *HttpClientModule) Init(proxyUrl string, maxpool int, dialTimeout time.Duration,dialKeepAlive time.Duration,idleConnTimeout time.Duration,timeout time.Duration) {
|
||||
type ProxyFun func(_ *http.Request) (*url.URL, error)
|
||||
var proxyFun ProxyFun
|
||||
if proxyUrl != "" {
|
||||
@@ -55,16 +63,16 @@ func (m *HttpClientModule) Init(maxpool int, proxyUrl string) {
|
||||
m.client = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 5 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
Timeout: dialTimeout,
|
||||
KeepAlive: dialKeepAlive,
|
||||
}).DialContext,
|
||||
MaxIdleConns: maxpool,
|
||||
MaxIdleConnsPerHost: maxpool,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
IdleConnTimeout: idleConnTimeout,
|
||||
Proxy: proxyFun,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
Timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package mysqlmondule
|
||||
package mysqlmodule
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package mysqlmondule
|
||||
package mysqlmodule
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
@@ -104,11 +104,11 @@ func (cs *CustomerSubscriber) UnSubscribe() {
|
||||
func (cs *CustomerSubscriber) LoadLastIndex() {
|
||||
for {
|
||||
if atomic.LoadInt32(&cs.isStop) != 0 {
|
||||
log.SRelease("topic ", cs.topic, " out of subscription")
|
||||
log.Info("topic ", cs.topic, " out of subscription")
|
||||
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)
|
||||
if ret == true {
|
||||
if lastIndex > 0 {
|
||||
@@ -116,18 +116,18 @@ func (cs *CustomerSubscriber) LoadLastIndex() {
|
||||
} 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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func (cs *CustomerSubscriber) SubscribeRun() {
|
||||
defer cs.subscriber.queueWait.Done()
|
||||
log.SRelease("topic ", cs.topic, " start subscription")
|
||||
log.Info("topic ", cs.topic, " start subscription")
|
||||
|
||||
//加载之前的位置
|
||||
if cs.subscribeMethod == MethodLast {
|
||||
@@ -136,7 +136,7 @@ func (cs *CustomerSubscriber) SubscribeRun() {
|
||||
|
||||
for {
|
||||
if atomic.LoadInt32(&cs.isStop) != 0 {
|
||||
log.SRelease("topic ", cs.topic, " out of subscription")
|
||||
log.Info("topic ", cs.topic, " out of subscription")
|
||||
break
|
||||
}
|
||||
|
||||
@@ -146,14 +146,14 @@ func (cs *CustomerSubscriber) SubscribeRun() {
|
||||
|
||||
//todo 检测退出
|
||||
if cs.subscribe() == false {
|
||||
log.SRelease("topic ", cs.topic, " out of subscription")
|
||||
log.Info("topic ", cs.topic, " out of subscription")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//删除订阅关系
|
||||
cs.subscriber.removeCustomer(cs.customerId, cs)
|
||||
log.SRelease("topic ", cs.topic, " unsubscription")
|
||||
log.Info("topic ", cs.topic, " unsubscription")
|
||||
}
|
||||
|
||||
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 {
|
||||
time.Sleep(time.Second * 1)
|
||||
continue
|
||||
|
||||
@@ -63,7 +63,7 @@ func (ms *MessageQueueService) ReadCfg() error {
|
||||
maxProcessTopicBacklogNum, ok := mapDBServiceCfg["MaxProcessTopicBacklogNum"]
|
||||
if ok == false {
|
||||
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 {
|
||||
ms.maxProcessTopicBacklogNum = int32(maxProcessTopicBacklogNum.(float64))
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func (ms *MessageQueueService) ReadCfg() error {
|
||||
memoryQueueLen, ok := mapDBServiceCfg["MemoryQueueLen"]
|
||||
if ok == false {
|
||||
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 {
|
||||
ms.memoryQueueLen = int32(memoryQueueLen.(float64))
|
||||
}
|
||||
|
||||
@@ -1,18 +1,49 @@
|
||||
package messagequeueservice
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/duanhf2012/origin/log"
|
||||
"github.com/duanhf2012/origin/service"
|
||||
"github.com/duanhf2012/origin/sysmodule/mongodbmodule"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"sunserver/common/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
const MaxDays = 180
|
||||
|
||||
type DataType interface {
|
||||
int | uint | int64 | uint64 | float32 | float64 | int32 | uint32 | int16 | uint16
|
||||
}
|
||||
|
||||
func convertToNumber[DType DataType](val interface{}) (error, DType) {
|
||||
switch val.(type) {
|
||||
case int64:
|
||||
return nil, DType(val.(int64))
|
||||
case int:
|
||||
return nil, DType(val.(int))
|
||||
case uint:
|
||||
return nil, DType(val.(uint))
|
||||
case uint64:
|
||||
return nil, DType(val.(uint64))
|
||||
case float32:
|
||||
return nil, DType(val.(float32))
|
||||
case float64:
|
||||
return nil, DType(val.(float64))
|
||||
case int32:
|
||||
return nil, DType(val.(int32))
|
||||
case uint32:
|
||||
return nil, DType(val.(uint32))
|
||||
case int16:
|
||||
return nil, DType(val.(int16))
|
||||
case uint16:
|
||||
return nil, DType(val.(uint16))
|
||||
}
|
||||
|
||||
return errors.New("unsupported type"), 0
|
||||
}
|
||||
|
||||
type MongoPersist struct {
|
||||
service.Module
|
||||
mongo mongodbmodule.MongoModule
|
||||
@@ -363,7 +394,7 @@ func (mp *MongoPersist) GetIndex(topicData *TopicData) uint64 {
|
||||
|
||||
for _, e := range document {
|
||||
if e.Key == "_id" {
|
||||
errC, seq := util.ConvertToNumber[uint64](e.Value)
|
||||
errC, seq := convertToNumber[uint64](e.Value)
|
||||
if errC != nil {
|
||||
log.Error("value is error:%s,%+v, ", errC.Error(), e.Value)
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ func (ss *Subscriber) TopicSubscribe(rpcHandler rpc.IRpcHandler, subScribeType r
|
||||
}
|
||||
|
||||
if ok == true {
|
||||
log.SRelease("repeat subscription for customer ", customerId)
|
||||
log.Info("repeat subscription for customer ", customerId)
|
||||
} else {
|
||||
log.SRelease("subscription for customer ", customerId)
|
||||
log.Info("subscription for customer ", customerId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func (tr *TopicRoom) Stop() {
|
||||
func (tr *TopicRoom) topicRoomRun() {
|
||||
defer tr.queueWait.Done()
|
||||
|
||||
log.SRelease("topic room ", tr.topic, " is running..")
|
||||
log.Info("topic room ", tr.topic, " is running..")
|
||||
for {
|
||||
if atomic.LoadInt32(&tr.isStop) != 0 {
|
||||
break
|
||||
@@ -145,5 +145,5 @@ func (tr *TopicRoom) topicRoomRun() {
|
||||
}
|
||||
tr.customerLocker.Unlock()
|
||||
|
||||
log.SRelease("topic room ", tr.topic, " is stop")
|
||||
log.Info("topic room ", tr.topic, " is stop")
|
||||
}
|
||||
|
||||
@@ -142,13 +142,13 @@ func (mp *MongoPersist) OnSetupRank(manual bool,rankSkip *RankSkip) error{
|
||||
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())
|
||||
if err != nil {
|
||||
log.SError("load from db is fail :%s",err.Error())
|
||||
return err
|
||||
}
|
||||
log.SRelease("finish load rank ",rankSkip.GetRankName()," from mongodb.")
|
||||
log.Info("finish load rank ",rankSkip.GetRankName()," from mongodb.")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ func (mp *MongoPersist) JugeTimeoutSave() bool{
|
||||
|
||||
func (mp *MongoPersist) persistCoroutine(){
|
||||
defer mp.waitGroup.Done()
|
||||
for atomic.LoadInt32(&mp.stop)==0 || mp.hasPersistData(){
|
||||
for atomic.LoadInt32(&mp.stop)==0 {
|
||||
//间隔时间sleep
|
||||
time.Sleep(time.Second*1)
|
||||
|
||||
@@ -297,7 +297,7 @@ func (mp *MongoPersist) saveToDB(){
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
errString := fmt.Sprint(r)
|
||||
log.SError(" Core dump info[", errString, "]\n", string(buf[:l]))
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -357,7 +357,7 @@ func (mp *MongoPersist) removeRankData(rankId uint64,keys []uint64) bool {
|
||||
|
||||
func (mp *MongoPersist) upsertToDB(collectName string,rankData *RankData) error{
|
||||
condition := bson.D{{"_id", rankData.Key}}
|
||||
upsert := bson.M{"_id":rankData.Key,"RefreshTime": rankData.refreshTimestamp, "SortData": rankData.SortData, "Data": rankData.Data,"ExData":rankData.ExData}
|
||||
upsert := bson.M{"_id":rankData.Key,"RefreshTime": rankData.RefreshTimestamp, "SortData": rankData.SortData, "Data": rankData.Data,"ExData":rankData.ExData}
|
||||
update := bson.M{"$set": upsert}
|
||||
|
||||
s := mp.mongo.TakeSession()
|
||||
|
||||
@@ -19,7 +19,7 @@ type RankData struct {
|
||||
Data []byte
|
||||
ExData []int64
|
||||
|
||||
refreshTimestamp int64 //刷新时间
|
||||
RefreshTimestamp int64 //刷新时间
|
||||
//bRelease bool
|
||||
ref bool
|
||||
compareFunc func(other skip.Comparator) int
|
||||
@@ -39,7 +39,7 @@ func NewRankData(isDec bool, data *rpc.RankData,refreshTimestamp int64) *RankDat
|
||||
ret.ExData = append(ret.ExData,d.InitValue+d.IncreaseValue)
|
||||
}
|
||||
|
||||
ret.refreshTimestamp = refreshTimestamp
|
||||
ret.RefreshTimestamp = refreshTimestamp
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ func (rs *RankSkip) UpsetRank(upsetData *rpc.RankData, refreshTimestamp int64, f
|
||||
//找到的情况对比排名数据是否有变化,无变化进行data更新,有变化则进行删除更新
|
||||
if compareIsEqual(rankNode.SortData, upsetData.SortData) {
|
||||
rankNode.Data = upsetData.GetData()
|
||||
rankNode.refreshTimestamp = refreshTimestamp
|
||||
rankNode.RefreshTimestamp = refreshTimestamp
|
||||
|
||||
if fromLoad == false {
|
||||
rs.rankModule.OnChangeRankData(rs, rankNode)
|
||||
|
||||
@@ -8,10 +8,11 @@ import (
|
||||
"github.com/duanhf2012/origin/network/processor"
|
||||
"github.com/duanhf2012/origin/node"
|
||||
"github.com/duanhf2012/origin/service"
|
||||
"sync/atomic"
|
||||
"sync"
|
||||
"time"
|
||||
"github.com/duanhf2012/origin/util/bytespool"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TcpService struct {
|
||||
@@ -52,18 +53,9 @@ type Client struct {
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) genId() uint64 {
|
||||
if node.GetNodeId()>MaxNodeId{
|
||||
panic("nodeId exceeds the maximum!")
|
||||
}
|
||||
|
||||
newSeed := atomic.AddUint32(&seed,1) % MaxSeed
|
||||
nowTime := uint64(time.Now().Unix())%MaxTime
|
||||
return (uint64(node.GetNodeId())<<50)|(nowTime<<19)|uint64(newSeed)
|
||||
}
|
||||
|
||||
|
||||
func GetNodeId(agentId uint64) int {
|
||||
return int(agentId>>50)
|
||||
return (uint64(node.GetNodeId()%MaxNodeId)<<50)|(nowTime<<19)|uint64(newSeed)
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) OnInit() error{
|
||||
@@ -170,7 +162,7 @@ func (slf *Client) Run() {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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)
|
||||
bytes,err := slf.tcpConn.ReadMsg()
|
||||
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
|
||||
}
|
||||
data,err:=slf.tcpService.process.Unmarshal(slf.id,bytes)
|
||||
@@ -277,14 +269,14 @@ func (tcpService *TcpService) GetConnNum() int {
|
||||
return connNum
|
||||
}
|
||||
|
||||
func (server *TcpService) SetNetMempool(mempool network.INetMempool){
|
||||
func (server *TcpService) SetNetMempool(mempool bytespool.IBytesMempool){
|
||||
server.tcpServer.SetNetMempool(mempool)
|
||||
}
|
||||
|
||||
func (server *TcpService) GetNetMempool() network.INetMempool{
|
||||
func (server *TcpService) GetNetMempool() bytespool.IBytesMempool {
|
||||
return server.tcpServer.GetNetMempool()
|
||||
}
|
||||
|
||||
func (server *TcpService) ReleaseNetMem(byteBuff []byte) {
|
||||
server.tcpServer.GetNetMempool().ReleaseByteSlice(byteBuff)
|
||||
server.tcpServer.GetNetMempool().ReleaseBytes(byteBuff)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package network
|
||||
package bytespool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type INetMempool interface {
|
||||
MakeByteSlice(size int) []byte
|
||||
ReleaseByteSlice(byteBuff []byte) bool
|
||||
type IBytesMempool interface {
|
||||
MakeBytes(size int) []byte
|
||||
ReleaseBytes(byteBuff []byte) bool
|
||||
}
|
||||
|
||||
type memAreaPool struct {
|
||||
@@ -16,7 +16,7 @@ type memAreaPool struct {
|
||||
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() {
|
||||
for i := 0; i < len(memAreaPoolList); i++ {
|
||||
@@ -68,7 +68,7 @@ func (areaPool *memAreaPool) releaseByteSlice(byteBuff []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (areaPool *memAreaPool) MakeByteSlice(size int) []byte {
|
||||
func (areaPool *memAreaPool) MakeBytes(size int) []byte {
|
||||
for i := 0; i < len(memAreaPoolList); i++ {
|
||||
if size <= memAreaPoolList[i].maxAreaValue {
|
||||
return memAreaPoolList[i].makeByteSlice(size)
|
||||
@@ -78,7 +78,7 @@ func (areaPool *memAreaPool) MakeByteSlice(size int) []byte {
|
||||
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++ {
|
||||
if cap(byteBuff) <= memAreaPoolList[i].maxAreaValue {
|
||||
return memAreaPoolList[i].releaseByteSlice(byteBuff)
|
||||
@@ -1,6 +1,8 @@
|
||||
package math
|
||||
|
||||
import "github.com/duanhf2012/origin/log"
|
||||
import (
|
||||
"github.com/duanhf2012/origin/log"
|
||||
)
|
||||
|
||||
type NumberType interface {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
func Add[NumType NumberType](number1 NumType, number2 NumType) NumType {
|
||||
func AddSafe[NumType NumberType](number1 NumType, number2 NumType) (NumType, bool) {
|
||||
ret := 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)
|
||||
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 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
|
||||
}
|
||||
|
||||
func Sub[NumType NumberType](number1 NumType, number2 NumType) NumType {
|
||||
ret := 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)
|
||||
}
|
||||
|
||||
ret, _ := SubSafe(number1, number2)
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
func Mul[NumType NumberType](number1 NumType, number2 NumType) NumType {
|
||||
ret := 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)
|
||||
ret, _ := MulSafe(number1, number2)
|
||||
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
|
||||
}
|
||||
|
||||
25
util/sysprocess/process.go
Normal file
25
util/sysprocess/process.go
Normal 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()))
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"time"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// ITimer
|
||||
@@ -29,7 +30,7 @@ type OnAddTimer func(timer ITimer)
|
||||
// Timer
|
||||
type Timer struct {
|
||||
Id uint64
|
||||
cancelled bool //是否关闭
|
||||
cancelled int32 //是否关闭
|
||||
C chan ITimer //定时器管道
|
||||
interval time.Duration // 时间间隔(用于循环定时器)
|
||||
fireTime time.Time // 触发时间
|
||||
@@ -131,7 +132,7 @@ func (t *Timer) Do() {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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() {
|
||||
t.cancelled = true
|
||||
atomic.StoreInt32(&t.cancelled,1)
|
||||
}
|
||||
|
||||
// 判断定时器是否已经取消
|
||||
func (t *Timer) IsActive() bool {
|
||||
return !t.cancelled
|
||||
return atomic.LoadInt32(&t.cancelled) == 0
|
||||
}
|
||||
|
||||
func (t *Timer) GetName() string {
|
||||
@@ -217,7 +218,7 @@ func (c *Cron) Do() {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
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)
|
||||
l := runtime.Stack(buf, false)
|
||||
errString := fmt.Sprint(r)
|
||||
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user