mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-09 11:14:43 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1174b47475 | ||
|
|
18fff3b567 | ||
|
|
7ab6c88f9c | ||
|
|
6b64de06a2 | ||
|
|
95b153f8cf |
43
README.md
43
README.md
@@ -767,34 +767,57 @@ func (slf *TestService7) GoTest(){
|
||||
//slf.OpenConcurrent(5, 10, 1000000)
|
||||
```
|
||||
|
||||
普通调用可以使用以下方法:
|
||||
使用示例如下:
|
||||
```
|
||||
func (slf *TestService1) testAsyncDo() {
|
||||
|
||||
func (slf *TestService13) testAsyncDo() {
|
||||
var context struct {
|
||||
data int64
|
||||
}
|
||||
slf.AsyncDo(func() {
|
||||
|
||||
//1.示例普通使用
|
||||
//参数一的函数在其他协程池中执行完成,将执行完成事件放入服务工作协程,
|
||||
//参数二的函数在服务协程中执行,是协程安全的。
|
||||
slf.AsyncDo(func() bool {
|
||||
//该函数回调在协程池中执行
|
||||
context.data = 100
|
||||
return true
|
||||
}, func(err error) {
|
||||
//函数将在服务协程中执行
|
||||
fmt.Print(context.data) //显示100
|
||||
})
|
||||
}
|
||||
```
|
||||
以下方法将函数扔到任务管道中,由协程池去抢执行。但某些任务是由先后顺序的,可以使用以下方法:
|
||||
```
|
||||
func (slf *TestService1) testAsyncDoByQueue() {
|
||||
queueId := int64(1)
|
||||
|
||||
//2.示例按队列顺序
|
||||
//参数一传入队列Id,同一个队列Id将在协程池中被排队执行
|
||||
//以下进行两次调用,因为两次都传入参数queueId都为1,所以它们会都进入queueId为1的排队执行
|
||||
queueId := int64(1)
|
||||
for i := 0; i < 2; i++ {
|
||||
slf.AsyncDoByQueue(queueId, func() {
|
||||
slf.AsyncDoByQueue(queueId, func() bool {
|
||||
//该函数会被2次调用,但是会排队执行
|
||||
return true
|
||||
}, func(err error) {
|
||||
//函数将在服务协程中执行
|
||||
})
|
||||
}
|
||||
|
||||
//3.函数参数可以某中一个为空
|
||||
//参数二函数将被延迟执行
|
||||
slf.AsyncDo(nil, func(err error) {
|
||||
//将在下
|
||||
})
|
||||
|
||||
//参数一函数在协程池中执行,但没有在服务协程中回调
|
||||
slf.AsyncDo(func() bool {
|
||||
return true
|
||||
}, nil)
|
||||
|
||||
//4.函数返回值控制不进行回调
|
||||
slf.AsyncDo(func() bool {
|
||||
//返回false时,参数二函数将不会被执行; 为true时,则会被执行
|
||||
return false
|
||||
}, func(err error) {
|
||||
//该函数将不会被执行
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ const defaultMaxTaskChannelNum = 1000000
|
||||
type IConcurrent interface {
|
||||
OpenConcurrentByNumCPU(cpuMul float32)
|
||||
OpenConcurrent(minGoroutineNum int32, maxGoroutineNum int32, maxTaskChannelNum int)
|
||||
AsyncDoByQueue(queueId int64, fn func(), cb func(err error))
|
||||
AsyncDo(f func(), cb func(err error))
|
||||
AsyncDoByQueue(queueId int64, fn func() bool, cb func(err error))
|
||||
AsyncDo(f func() bool, cb func(err error))
|
||||
}
|
||||
|
||||
type Concurrent struct {
|
||||
@@ -40,11 +40,11 @@ func (c *Concurrent) OpenConcurrent(minGoroutineNum int32, maxGoroutineNum int32
|
||||
c.dispatch.open(minGoroutineNum, maxGoroutineNum, c.tasks, c.cbChannel)
|
||||
}
|
||||
|
||||
func (c *Concurrent) AsyncDo(f func(), cb func(err error)) {
|
||||
func (c *Concurrent) AsyncDo(f func() bool, cb func(err error)) {
|
||||
c.AsyncDoByQueue(0, f, cb)
|
||||
}
|
||||
|
||||
func (c *Concurrent) AsyncDoByQueue(queueId int64, fn func(), cb func(err error)) {
|
||||
func (c *Concurrent) AsyncDoByQueue(queueId int64, fn func() bool, cb func(err error)) {
|
||||
if cap(c.tasks) == 0 {
|
||||
panic("not open concurrent")
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
type task struct {
|
||||
queueId int64
|
||||
fn func()
|
||||
fn func() bool
|
||||
cb func(err error)
|
||||
}
|
||||
|
||||
@@ -60,17 +60,18 @@ func (w *worker) exec(t *task) {
|
||||
cb(errors.New(errString))
|
||||
}
|
||||
|
||||
w.endCallFun(t)
|
||||
w.endCallFun(true,t)
|
||||
log.SError("core dump info[", errString, "]\n", string(buf[:l]))
|
||||
}
|
||||
}()
|
||||
|
||||
t.fn()
|
||||
w.endCallFun(t)
|
||||
w.endCallFun(t.fn(),t)
|
||||
}
|
||||
|
||||
func (w *worker) endCallFun(t *task) {
|
||||
w.pushAsyncDoCallbackEvent(t.cb)
|
||||
func (w *worker) endCallFun(isDocallBack bool,t *task) {
|
||||
if isDocallBack {
|
||||
w.pushAsyncDoCallbackEvent(t.cb)
|
||||
}
|
||||
|
||||
if t.queueId != 0 {
|
||||
w.pushQueueTaskFinishEvent(t.queueId)
|
||||
|
||||
@@ -64,20 +64,24 @@ func (client *TCPClient) init() {
|
||||
if client.cons != nil {
|
||||
log.SFatal("client is running")
|
||||
}
|
||||
if client.LenMsgLen == 0 {
|
||||
client.LenMsgLen = Default_LenMsgLen
|
||||
}
|
||||
|
||||
if client.MinMsgLen == 0 {
|
||||
client.MinMsgLen = Default_MinMsgLen
|
||||
}
|
||||
if client.MaxMsgLen == 0 {
|
||||
client.MaxMsgLen = Default_MaxMsgLen
|
||||
}
|
||||
if client.LenMsgLen ==0 {
|
||||
client.LenMsgLen = Default_LenMsgLen
|
||||
}
|
||||
maxMsgLen := client.MsgParser.getMaxMsgLen(client.LenMsgLen)
|
||||
if client.MaxMsgLen > maxMsgLen {
|
||||
client.MaxMsgLen = maxMsgLen
|
||||
log.SRelease("invalid MaxMsgLen, reset to ", maxMsgLen)
|
||||
}
|
||||
|
||||
client.cons = make(ConnSet)
|
||||
client.closeFlag = false
|
||||
|
||||
// msg parser
|
||||
client.MsgParser.init()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,30 +20,22 @@ type MsgParser struct {
|
||||
}
|
||||
|
||||
|
||||
func (p *MsgParser) init(){
|
||||
var max uint32
|
||||
func (p *MsgParser) getMaxMsgLen(lenMsgLen int) uint32 {
|
||||
switch p.LenMsgLen {
|
||||
case 1:
|
||||
max = math.MaxUint8
|
||||
return math.MaxUint8
|
||||
case 2:
|
||||
max = math.MaxUint16
|
||||
return math.MaxUint16
|
||||
case 4:
|
||||
max = math.MaxUint32
|
||||
return math.MaxUint32
|
||||
default:
|
||||
panic("LenMsgLen value must be 1 or 2 or 4")
|
||||
}
|
||||
|
||||
if p.MinMsgLen > max {
|
||||
p.MinMsgLen = max
|
||||
}
|
||||
|
||||
if p.MaxMsgLen > max {
|
||||
p.MaxMsgLen = max
|
||||
}
|
||||
|
||||
p.INetMempool = NewMemAreaPool()
|
||||
}
|
||||
|
||||
func (p *MsgParser) init(){
|
||||
p.INetMempool = NewMemAreaPool()
|
||||
}
|
||||
|
||||
// goroutine safe
|
||||
func (p *MsgParser) Read(conn *TCPConn) ([]byte, error) {
|
||||
|
||||
@@ -7,14 +7,16 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const Default_ReadDeadline = time.Second*30 //30s
|
||||
const Default_WriteDeadline = time.Second*30 //30s
|
||||
const Default_MaxConnNum = 9000
|
||||
const Default_PendingWriteNum = 10000
|
||||
const Default_LittleEndian = false
|
||||
const Default_MinMsgLen = 2
|
||||
const Default_MaxMsgLen = 65535
|
||||
const Default_LenMsgLen = 2
|
||||
const(
|
||||
Default_ReadDeadline = time.Second*30 //默认读超时30s
|
||||
Default_WriteDeadline = time.Second*30 //默认写超时30s
|
||||
Default_MaxConnNum = 1000000 //默认最大连接数
|
||||
Default_PendingWriteNum = 100000 //单连接写消息Channel容量
|
||||
Default_LittleEndian = false //默认大小端
|
||||
Default_MinMsgLen = 2 //最小消息长度2byte
|
||||
Default_LenMsgLen = 2 //包头字段长度占用2byte
|
||||
Default_MaxMsgLen = 65535 //最大消息长度
|
||||
)
|
||||
|
||||
type TCPServer struct {
|
||||
Addr string
|
||||
@@ -29,8 +31,7 @@ type TCPServer struct {
|
||||
mutexConns sync.Mutex
|
||||
wgLn sync.WaitGroup
|
||||
wgConns sync.WaitGroup
|
||||
|
||||
// msg parser
|
||||
|
||||
MsgParser
|
||||
}
|
||||
|
||||
@@ -49,14 +50,15 @@ func (server *TCPServer) init() {
|
||||
server.MaxConnNum = Default_MaxConnNum
|
||||
log.SRelease("invalid MaxConnNum, reset to ", server.MaxConnNum)
|
||||
}
|
||||
|
||||
if server.PendingWriteNum <= 0 {
|
||||
server.PendingWriteNum = Default_PendingWriteNum
|
||||
log.SRelease("invalid PendingWriteNum, reset to ", server.PendingWriteNum)
|
||||
}
|
||||
|
||||
if server.MinMsgLen <= 0 {
|
||||
server.MinMsgLen = Default_MinMsgLen
|
||||
log.SRelease("invalid MinMsgLen, reset to ", server.MinMsgLen)
|
||||
if server.LenMsgLen <= 0 {
|
||||
server.LenMsgLen = Default_LenMsgLen
|
||||
log.SRelease("invalid LenMsgLen, reset to ", server.LenMsgLen)
|
||||
}
|
||||
|
||||
if server.MaxMsgLen <= 0 {
|
||||
@@ -64,6 +66,17 @@ func (server *TCPServer) init() {
|
||||
log.SRelease("invalid MaxMsgLen, reset to ", server.MaxMsgLen)
|
||||
}
|
||||
|
||||
maxMsgLen := server.MsgParser.getMaxMsgLen(server.LenMsgLen)
|
||||
if server.MaxMsgLen > maxMsgLen {
|
||||
server.MaxMsgLen = maxMsgLen
|
||||
log.SRelease("invalid MaxMsgLen, reset to ", maxMsgLen)
|
||||
}
|
||||
|
||||
if server.MinMsgLen <= 0 {
|
||||
server.MinMsgLen = Default_MinMsgLen
|
||||
log.SRelease("invalid MinMsgLen, reset to ", server.MinMsgLen)
|
||||
}
|
||||
|
||||
if server.WriteDeadline == 0 {
|
||||
server.WriteDeadline = Default_WriteDeadline
|
||||
log.SRelease("invalid WriteDeadline, reset to ", server.WriteDeadline.Seconds(),"s")
|
||||
@@ -74,18 +87,12 @@ func (server *TCPServer) init() {
|
||||
log.SRelease("invalid ReadDeadline, reset to ", server.ReadDeadline.Seconds(),"s")
|
||||
}
|
||||
|
||||
if server.LenMsgLen == 0 {
|
||||
server.LenMsgLen = Default_LenMsgLen
|
||||
}
|
||||
|
||||
if server.NewAgent == nil {
|
||||
log.SFatal("NewAgent must not be nil")
|
||||
}
|
||||
|
||||
server.ln = ln
|
||||
server.conns = make(ConnSet)
|
||||
server.INetMempool = NewMemAreaPool()
|
||||
|
||||
server.MsgParser.init()
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,19 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const MaxCheckCallRpcCount = 1000
|
||||
const MaxPendingWriteNum = 200000
|
||||
const ConnectInterval = 2*time.Second
|
||||
const RpcConnNum = 1
|
||||
const RpcLenMsgLen = 4
|
||||
const RpcMinMsgLen = 2
|
||||
const CheckRpcCallTimeoutInterval = 5*time.Second
|
||||
const DefaultRpcTimeout = 15*time.Second
|
||||
const(
|
||||
DefaultRpcConnNum = 1
|
||||
DefaultRpcLenMsgLen = 4
|
||||
DefaultRpcMinMsgLen = 2
|
||||
DefaultMaxCheckCallRpcCount = 1000
|
||||
DefaultMaxPendingWriteNum = 200000
|
||||
|
||||
|
||||
DefaultConnectInterval = 2*time.Second
|
||||
DefaultCheckRpcCallTimeoutInterval = 5*time.Second
|
||||
DefaultRpcTimeout = 15*time.Second
|
||||
)
|
||||
|
||||
var clientSeq uint32
|
||||
|
||||
type IRealClient interface {
|
||||
@@ -64,7 +69,7 @@ func (bc *Client) makeCallFail(call *Call) {
|
||||
|
||||
func (bc *Client) checkRpcCallTimeout() {
|
||||
for{
|
||||
time.Sleep(CheckRpcCallTimeoutInterval)
|
||||
time.Sleep(DefaultCheckRpcCallTimeoutInterval)
|
||||
now := time.Now()
|
||||
|
||||
for i := 0; i < bc.maxCheckCallRpcCount; i++ {
|
||||
|
||||
@@ -119,7 +119,7 @@ func NewLClient(nodeId int) *Client{
|
||||
client := &Client{}
|
||||
client.clientId = atomic.AddUint32(&clientSeq, 1)
|
||||
client.nodeId = nodeId
|
||||
client.maxCheckCallRpcCount = MaxCheckCallRpcCount
|
||||
client.maxCheckCallRpcCount = DefaultMaxCheckCallRpcCount
|
||||
client.callRpcTimeout = DefaultRpcTimeout
|
||||
|
||||
lClient := &LClient{}
|
||||
|
||||
@@ -211,19 +211,19 @@ func NewRClient(nodeId int, addr string, maxRpcParamLen uint32,triggerRpcConnEve
|
||||
client := &Client{}
|
||||
client.clientId = atomic.AddUint32(&clientSeq, 1)
|
||||
client.nodeId = nodeId
|
||||
client.maxCheckCallRpcCount = MaxCheckCallRpcCount
|
||||
client.maxCheckCallRpcCount = DefaultMaxCheckCallRpcCount
|
||||
client.callRpcTimeout = DefaultRpcTimeout
|
||||
|
||||
c:= &RClient{}
|
||||
c.selfClient = client
|
||||
c.Addr = addr
|
||||
c.ConnectInterval = ConnectInterval
|
||||
c.PendingWriteNum = MaxPendingWriteNum
|
||||
c.ConnectInterval = DefaultConnectInterval
|
||||
c.PendingWriteNum = DefaultMaxPendingWriteNum
|
||||
c.AutoReconnect = true
|
||||
c.TriggerRpcConnEvent = triggerRpcConnEvent
|
||||
c.ConnNum = RpcConnNum
|
||||
c.LenMsgLen = RpcLenMsgLen
|
||||
c.MinMsgLen = RpcMinMsgLen
|
||||
c.ConnNum = DefaultRpcConnNum
|
||||
c.LenMsgLen = DefaultRpcLenMsgLen
|
||||
c.MinMsgLen = DefaultRpcMinMsgLen
|
||||
c.ReadDeadline = Default_ReadWriteDeadline
|
||||
c.WriteDeadline = Default_ReadWriteDeadline
|
||||
c.LittleEndian = LittleEndian
|
||||
|
||||
@@ -71,7 +71,6 @@ func (server *Server) Start(listenAddr string, maxRpcParamLen uint32) {
|
||||
}
|
||||
|
||||
server.rpcServer.Addr = ":" + splitAddr[1]
|
||||
server.rpcServer.LenMsgLen = 4 //uint16
|
||||
server.rpcServer.MinMsgLen = 2
|
||||
if maxRpcParamLen > 0 {
|
||||
server.rpcServer.MaxMsgLen = maxRpcParamLen
|
||||
@@ -85,6 +84,8 @@ func (server *Server) Start(listenAddr string, maxRpcParamLen uint32) {
|
||||
server.rpcServer.LittleEndian = LittleEndian
|
||||
server.rpcServer.WriteDeadline = Default_ReadWriteDeadline
|
||||
server.rpcServer.ReadDeadline = Default_ReadWriteDeadline
|
||||
server.rpcServer.LenMsgLen = DefaultRpcLenMsgLen
|
||||
|
||||
server.rpcServer.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ var timerDispatcherLen = 100000
|
||||
var maxServiceEventChannelNum = 2000000
|
||||
|
||||
type IService interface {
|
||||
concurrent.IConcurrent
|
||||
Init(iService IService,getClientFun rpc.FuncRpcClient,getServerFun rpc.FuncRpcServer,serviceCfg interface{})
|
||||
Stop()
|
||||
Start()
|
||||
|
||||
@@ -90,6 +90,10 @@ func (tcpService *TcpService) OnInit() error{
|
||||
if ok == true {
|
||||
tcpService.tcpServer.LittleEndian = LittleEndian.(bool)
|
||||
}
|
||||
LenMsgLen,ok := tcpCfg["LenMsgLen"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.LenMsgLen = int(LenMsgLen.(float64))
|
||||
}
|
||||
MinMsgLen,ok := tcpCfg["MinMsgLen"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.MinMsgLen = uint32(MinMsgLen.(float64))
|
||||
|
||||
Reference in New Issue
Block a user