Commit 1e0ac263 authored by AlexStocks's avatar AlexStocks

Imp: just treat task pool as a independent role

parent ac39a3ba
...@@ -51,9 +51,6 @@ type client struct { ...@@ -51,9 +51,6 @@ type client struct {
newSession NewSessionCallback newSession NewSessionCallback
ssMap map[Session]struct{} ssMap map[Session]struct{}
// task queue pool
tQPool *taskPool
sync.Once sync.Once
done chan struct{} done chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
...@@ -79,10 +76,6 @@ func newClient(t EndPointType, opts ...ClientOption) *client { ...@@ -79,10 +76,6 @@ func newClient(t EndPointType, opts ...ClientOption) *client {
c.ssMap = make(map[Session]struct{}, c.number) c.ssMap = make(map[Session]struct{}, c.number)
if c.tQPoolSize > 0 {
c.tQPool = newTaskPool(c.taskPoolOptions)
}
return c return c
} }
...@@ -357,7 +350,6 @@ func (c *client) connect() { ...@@ -357,7 +350,6 @@ func (c *client) connect() {
} }
err = c.newSession(ss) err = c.newSession(ss)
if err == nil { if err == nil {
ss.(*session).SetTaskPool(c.tQPool)
ss.(*session).run() ss.(*session).run()
c.Lock() c.Lock()
if c.ssMap == nil { if c.ssMap == nil {
...@@ -429,10 +421,6 @@ func (c *client) stop() { ...@@ -429,10 +421,6 @@ func (c *client) stop() {
} }
c.ssMap = nil c.ssMap = nil
if c.tQPool != nil {
c.tQPool.close()
c.tQPool = nil
}
c.Unlock() c.Unlock()
}) })
} }
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
package getty package getty
import (
"fmt"
)
///////////////////////////////////////// /////////////////////////////////////////
// Server Options // Server Options
///////////////////////////////////////// /////////////////////////////////////////
...@@ -19,9 +23,6 @@ type ServerOption func(*ServerOptions) ...@@ -19,9 +23,6 @@ type ServerOption func(*ServerOptions)
type ServerOptions struct { type ServerOptions struct {
addr string addr string
// task pool
taskPoolOptions
// websocket // websocket
path string path string
cert string cert string
...@@ -36,27 +37,6 @@ func WithLocalAddress(addr string) ServerOption { ...@@ -36,27 +37,6 @@ func WithLocalAddress(addr string) ServerOption {
} }
} }
// @size is the task queue pool size
func WithServerTaskPoolSize(size int32) ServerOption {
return func(o *ServerOptions) {
o.taskPoolOptions.tQPoolSize = size
}
}
// @length is the task queue length
func WithServerTaskQueueLength(length int32) ServerOption {
return func(o *ServerOptions) {
o.taskPoolOptions.tQLen = length
}
}
// @number is the task queue number
func WithServerTaskQueueNumber(number int32) ServerOption {
return func(o *ServerOptions) {
o.taskPoolOptions.tQNumber = number
}
}
// @path: websocket request url path // @path: websocket request url path
func WithWebsocketServerPath(path string) ServerOption { func WithWebsocketServerPath(path string) ServerOption {
return func(o *ServerOptions) { return func(o *ServerOptions) {
...@@ -96,9 +76,6 @@ type ClientOptions struct { ...@@ -96,9 +76,6 @@ type ClientOptions struct {
number int number int
reconnectInterval int // reConnect Interval reconnectInterval int // reConnect Interval
// task pool
taskPoolOptions
// the cert file of wss server which may contain server domain, server ip, the starting effective date, effective // the cert file of wss server which may contain server domain, server ip, the starting effective date, effective
// duration, the hash alg, the len of the private key. // duration, the hash alg, the len of the private key.
// wss client will use it. // wss client will use it.
...@@ -126,30 +103,60 @@ func WithConnectionNumber(num int) ClientOption { ...@@ -126,30 +103,60 @@ func WithConnectionNumber(num int) ClientOption {
} }
} }
// @size is the task queue pool size // @cert is client certificate file. it can be empty.
func WithClientTaskPoolSize(size int32) ClientOption { func WithRootCertificateFile(cert string) ClientOption {
return func(o *ClientOptions) { return func(o *ClientOptions) {
o.taskPoolOptions.tQPoolSize = size o.cert = cert
} }
} }
// @length is the task queue length /////////////////////////////////////////
func WithClientTaskQueueLength(length int32) ClientOption { // Task Pool Options
return func(o *ClientOptions) { /////////////////////////////////////////
o.taskPoolOptions.tQLen = length
type TaskPoolOptions struct {
tQLen int // task queue length
tQNumber int // task queue number
tQPoolSize int // task pool size
}
func (o *TaskPoolOptions) validate() {
if o.tQPoolSize == 0 {
panic(fmt.Sprintf("[getty][task_pool] illegal pool size %d", o.tQPoolSize))
}
if o.tQLen == 0 {
o.tQLen = defaultTaskQLen
}
if o.tQNumber < 1 {
o.tQNumber = defaultTaskQNumber
}
if o.tQNumber > o.tQPoolSize {
o.tQNumber = o.tQPoolSize
} }
} }
// @number is the task queue number type TaskPoolOption func(*TaskPoolOptions)
func WithClientTaskQueueNumber(number int32) ClientOption {
return func(o *ClientOptions) { // @size is the task queue pool size
o.taskPoolOptions.tQNumber = number func WithTaskPoolTaskPoolSize(size int) TaskPoolOption {
return func(o *TaskPoolOptions) {
o.tQPoolSize = size
} }
} }
// @cert is client certificate file. it can be empty. // @length is the task queue length
func WithRootCertificateFile(cert string) ClientOption { func WithTaskPoolTaskQueueLength(length int) TaskPoolOption {
return func(o *ClientOptions) { return func(o *TaskPoolOptions) {
o.cert = cert o.tQLen = length
}
}
// @number is the task queue number
func WithTaskPoolTaskQueueNumber(number int) TaskPoolOption {
return func(o *TaskPoolOptions) {
o.tQNumber = number
} }
} }
...@@ -41,9 +41,6 @@ type server struct { ...@@ -41,9 +41,6 @@ type server struct {
endPointType EndPointType endPointType EndPointType
server *http.Server // for ws or wss server server *http.Server // for ws or wss server
// task queue pool
tQPool *taskPool
sync.Once sync.Once
done chan struct{} done chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
...@@ -67,10 +64,6 @@ func newServer(t EndPointType, opts ...ServerOption) *server { ...@@ -67,10 +64,6 @@ func newServer(t EndPointType, opts ...ServerOption) *server {
panic(fmt.Sprintf("@addr:%s", s.addr)) panic(fmt.Sprintf("@addr:%s", s.addr))
} }
if s.tQPoolSize > 0 {
s.tQPool = newTaskPool(s.taskPoolOptions)
}
return s return s
} }
...@@ -137,10 +130,6 @@ func (s *server) stop() { ...@@ -137,10 +130,6 @@ func (s *server) stop() {
s.pktListener.Close() s.pktListener.Close()
s.pktListener = nil s.pktListener = nil
} }
if s.tQPool != nil {
s.tQPool.close()
s.tQPool = nil
}
}) })
} }
} }
...@@ -263,7 +252,6 @@ func (s *server) runTcpEventLoop(newSession NewSessionCallback) { ...@@ -263,7 +252,6 @@ func (s *server) runTcpEventLoop(newSession NewSessionCallback) {
continue continue
} }
delay = 0 delay = 0
client.(*session).SetTaskPool(s.tQPool)
client.(*session).run() client.(*session).run()
} }
}() }()
...@@ -278,7 +266,6 @@ func (s *server) runUDPEventLoop(newSession NewSessionCallback) { ...@@ -278,7 +266,6 @@ func (s *server) runUDPEventLoop(newSession NewSessionCallback) {
if err := newSession(ss); err != nil { if err := newSession(ss); err != nil {
panic(err.Error()) panic(err.Error())
} }
ss.(*session).SetTaskPool(s.tQPool)
ss.(*session).run() ss.(*session).run()
} }
...@@ -335,7 +322,6 @@ func (s *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) { ...@@ -335,7 +322,6 @@ func (s *wsHandler) serveWSRequest(w http.ResponseWriter, r *http.Request) {
if ss.(*session).maxMsgLen > 0 { if ss.(*session).maxMsgLen > 0 {
conn.SetReadLimit(int64(ss.(*session).maxMsgLen)) conn.SetReadLimit(int64(ss.(*session).maxMsgLen))
} }
ss.(*session).SetTaskPool(s.server.tQPool)
ss.(*session).run() ss.(*session).run()
} }
......
...@@ -63,7 +63,7 @@ type session struct { ...@@ -63,7 +63,7 @@ type session struct {
// handle logic // handle logic
maxMsgLen int32 maxMsgLen int32
// task queue // task queue
tQPool *taskPool tPool *TaskPool
// heartbeat // heartbeat
period time.Duration period time.Duration
...@@ -89,7 +89,6 @@ func newSession(endPoint EndPoint, conn Connection) *session { ...@@ -89,7 +89,6 @@ func newSession(endPoint EndPoint, conn Connection) *session {
Connection: conn, Connection: conn,
maxMsgLen: maxReadBufLen, maxMsgLen: maxReadBufLen,
tQLen: defaultTaskQLen,
period: period, period: period,
...@@ -302,11 +301,11 @@ func (s *session) SetWaitTime(waitTime time.Duration) { ...@@ -302,11 +301,11 @@ func (s *session) SetWaitTime(waitTime time.Duration) {
} }
// set task pool // set task pool
func (s *session) SetTaskPool(p *taskPool) { func (s *session) SetTaskPool(p *TaskPool) {
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
s.tQPool = p s.tPool = p
} }
// set attribute of key @session:key // set attribute of key @session:key
...@@ -457,7 +456,7 @@ func (s *session) run() { ...@@ -457,7 +456,7 @@ func (s *session) run() {
s.wQ = make(chan interface{}, defaultQLen) s.wQ = make(chan interface{}, defaultQLen)
} }
if s.rQ == nil && s.tQPool == nil { if s.rQ == nil && s.tPool == nil {
s.rQ = make(chan interface{}, defaultQLen) s.rQ = make(chan interface{}, defaultQLen)
} }
...@@ -564,8 +563,8 @@ LOOP: ...@@ -564,8 +563,8 @@ LOOP:
} }
func (s *session) addTask(pkg interface{}) { func (s *session) addTask(pkg interface{}) {
if s.tQPool != nil { if s.tPool != nil {
s.tQPool.AddTask(task{session: s, pkg: pkg}) s.tPool.AddTask(task{session: s, pkg: pkg})
} else { } else {
s.rQ <- pkg s.rQ <- pkg
} }
......
package getty package getty
import ( import (
"fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
) )
...@@ -17,33 +16,9 @@ type task struct { ...@@ -17,33 +16,9 @@ type task struct {
pkg interface{} pkg interface{}
} }
type taskPoolOptions struct {
tQLen int32 // task queue length
tQNumber int32 // task queue number
tQPoolSize int32 // task pool size
}
func (o *taskPoolOptions) Validate() {
if o.tQPoolSize == 0 {
panic(fmt.Sprintf("[getty][task_pool] illegal pool size %d", o.tQPoolSize))
}
if o.tQLen == 0 {
o.tQLen = defaultTaskQLen
}
if o.tQNumber < 1 {
o.tQNumber = defaultTaskQNumber
}
if o.tQNumber > o.tQPoolSize {
o.tQNumber = o.tQPoolSize
}
}
// task pool: manage task ts // task pool: manage task ts
type taskPool struct { type TaskPool struct {
taskPoolOptions TaskPoolOptions
idx uint32 // round robin index idx uint32 // round robin index
qArray []chan task qArray []chan task
...@@ -54,16 +29,16 @@ type taskPool struct { ...@@ -54,16 +29,16 @@ type taskPool struct {
} }
// build a task pool // build a task pool
func newTaskPool(opts taskPoolOptions) *taskPool { func newTaskPool(opts TaskPoolOptions) *TaskPool {
opts.Validate() opts.validate()
p := &taskPool{ p := &TaskPool{
taskPoolOptions: opts, TaskPoolOptions: opts,
qArray: make([]chan task, opts.tQNumber), qArray: make([]chan task, opts.tQNumber),
done: make(chan struct{}), done: make(chan struct{}),
} }
for i := int32(0); i < p.tQNumber; i++ { for i := 0; i < p.tQNumber; i++ {
p.qArray[i] = make(chan task, p.tQLen) p.qArray[i] = make(chan task, p.tQLen)
} }
...@@ -71,8 +46,8 @@ func newTaskPool(opts taskPoolOptions) *taskPool { ...@@ -71,8 +46,8 @@ func newTaskPool(opts taskPoolOptions) *taskPool {
} }
// start task pool // start task pool
func (p *taskPool) start() { func (p *TaskPool) start() {
for i := int32(0); i < p.tQPoolSize; i++ { for i := 0; i < p.tQPoolSize; i++ {
p.wg.Add(1) p.wg.Add(1)
workerID := i workerID := i
q := p.qArray[workerID%p.tQNumber] q := p.qArray[workerID%p.tQNumber]
...@@ -81,7 +56,7 @@ func (p *taskPool) start() { ...@@ -81,7 +56,7 @@ func (p *taskPool) start() {
} }
// worker // worker
func (p *taskPool) run(id int, q chan task) { func (p *TaskPool) run(id int, q chan task) {
defer p.wg.Done() defer p.wg.Done()
var ( var (
...@@ -109,7 +84,7 @@ func (p *taskPool) run(id int, q chan task) { ...@@ -109,7 +84,7 @@ func (p *taskPool) run(id int, q chan task) {
} }
// add task // add task
func (p *taskPool) AddTask(t task) { func (p *TaskPool) AddTask(t task) {
id := atomic.AddUint32(&p.idx, 1) % defaultTaskQNumber id := atomic.AddUint32(&p.idx, 1) % defaultTaskQNumber
select { select {
...@@ -120,7 +95,7 @@ func (p *taskPool) AddTask(t task) { ...@@ -120,7 +95,7 @@ func (p *taskPool) AddTask(t task) {
} }
// stop all tasks // stop all tasks
func (p *taskPool) stop() { func (p *TaskPool) stop() {
select { select {
case <-p.done: case <-p.done:
return return
...@@ -132,7 +107,7 @@ func (p *taskPool) stop() { ...@@ -132,7 +107,7 @@ func (p *taskPool) stop() {
} }
// check whether the session has been closed. // check whether the session has been closed.
func (p *taskPool) isClosed() bool { func (p *TaskPool) isClosed() bool {
select { select {
case <-p.done: case <-p.done:
return true return true
...@@ -142,7 +117,7 @@ func (p *taskPool) isClosed() bool { ...@@ -142,7 +117,7 @@ func (p *taskPool) isClosed() bool {
} }
} }
func (p *taskPool) close() { func (p *TaskPool) close() {
p.stop() p.stop()
p.wg.Wait() p.wg.Wait()
for i := range p.qArray { for i := range p.qArray {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment