Commit 2e0aa29811785c6f64b79661328b8adee619c8eb
1 parent
38dd96b4
update 每条连接新增一条协程,用于接受处理网络数据的逻辑和定时器的逻辑, 防止数据竞争
Showing
8 changed files
with
49 additions
and
53 deletions
Show diff stats
src/components/net/conn.go
... | ... | @@ -30,6 +30,9 @@ type Connection struct { |
30 | 30 | |
31 | 31 | WBuffer chan []byte |
32 | 32 | |
33 | + updateFunc chan func() | |
34 | + readFunc chan func() | |
35 | + | |
33 | 36 | Quit chan *Connection |
34 | 37 | |
35 | 38 | Role *models.RoleModel |
... | ... | @@ -54,9 +57,11 @@ func NewConn(id int, conn net.Conn, s *Server) *Connection { |
54 | 57 | scanner: bufio.NewScanner(conn), |
55 | 58 | writer: bufio.NewWriter(conn), |
56 | 59 | WBuffer: make(chan []byte), |
60 | + updateFunc: make(chan func()), | |
61 | + readFunc: make(chan func()), | |
57 | 62 | Quit: make(chan *Connection), |
58 | 63 | lastHeartCheckTime: utils.Timex(), |
59 | - heartTimeoutCount: 0, | |
64 | + heartTimeoutCount: 0, | |
60 | 65 | } |
61 | 66 | } |
62 | 67 | |
... | ... | @@ -87,10 +92,7 @@ func (c *Connection) read() { |
87 | 92 | } |
88 | 93 | |
89 | 94 | req.Conn = c |
90 | - //得到需要处理此条连接的workerID | |
91 | - workerID := c.Id % c.Server.SConf.WorkerPoolSize | |
92 | - //将请求消息发送给任务队列 | |
93 | - c.Server.TaskQueue[workerID] <- func() { | |
95 | + c.readFunc <- func() { | |
94 | 96 | c.Server.DoMsgHandler(req) |
95 | 97 | } |
96 | 98 | |
... | ... | @@ -132,26 +134,41 @@ func (c *Connection) update() { |
132 | 134 | } |
133 | 135 | |
134 | 136 | if c.Role != nil { |
135 | - c.Server.TaskQueue[c.Id % c.Server.SConf.WorkerPoolSize] <- func() { | |
136 | - //role 获取Recover | |
137 | + c.updateFunc <- func() { | |
138 | + //role 恢复数据 | |
137 | 139 | c.Role.OnRecoverTimer(now) |
138 | 140 | } |
139 | 141 | } |
140 | 142 | } |
141 | 143 | |
144 | +func (c *Connection) flush() { | |
145 | + defer c.Stop() | |
146 | + for { | |
147 | + select { | |
148 | + case rf := <- c.readFunc: | |
149 | + rf() | |
150 | + case uf := <- c.updateFunc: | |
151 | + uf() | |
152 | + case <- c.Quit: | |
153 | + return | |
154 | + } | |
155 | + } | |
156 | +} | |
142 | 157 | |
143 | 158 | func (c *Connection) Start() { |
144 | 159 | go c.write() |
145 | 160 | go c.read() |
161 | + c.flush() | |
146 | 162 | } |
147 | 163 | |
148 | 164 | func (c *Connection) Stop() { |
165 | + logger.Debug("ID: %d close", c.Id) | |
149 | 166 | c.Conn.Close() |
167 | + c.Server.OnClose(c) | |
150 | 168 | } |
151 | 169 | |
152 | 170 | func (c *Connection) Quiting() { |
153 | - logger.Debug("ID: %d close", c.Id) | |
154 | - c.Server.OnClose(c) | |
171 | + c.Quit <- c | |
155 | 172 | } |
156 | 173 | |
157 | 174 | func (c *Connection) SendMsgByCode(errCode int32, cmd int32, data []byte){ | ... | ... |
src/components/net/msg.go
src/components/net/server.go
1 | 1 | package net |
2 | 2 | |
3 | 3 | import ( |
4 | + "context" | |
4 | 5 | "fmt" |
5 | 6 | "github.com/golang/protobuf/proto" |
6 | 7 | "net" |
7 | 8 | "plugin" |
8 | 9 | "pro2d/conf" |
9 | 10 | "pro2d/protos/pb" |
10 | - "pro2d/src/common" | |
11 | 11 | "pro2d/src/components/db" |
12 | 12 | "pro2d/src/components/etcd" |
13 | 13 | "pro2d/src/components/logger" |
... | ... | @@ -19,14 +19,11 @@ import ( |
19 | 19 | |
20 | 20 | type ActionHandler func (msg *MsgPkg) (int32, proto.Message) |
21 | 21 | var ActionMap map[pb.ProtoCode]ActionHandler |
22 | -var TimeWheel *timewheel.TimeWheel | |
23 | 22 | |
24 | 23 | type Server struct { |
25 | 24 | SConf *conf.SConf |
26 | 25 | Clients *sync.Map |
27 | 26 | EtcdClient *etcd.EtcdClient |
28 | - | |
29 | - TaskQueue []chan func() | |
30 | 27 | } |
31 | 28 | |
32 | 29 | func NewServer(sConf *conf.SConf) *Server { |
... | ... | @@ -34,34 +31,6 @@ func NewServer(sConf *conf.SConf) *Server { |
34 | 31 | SConf: sConf, |
35 | 32 | Clients: new(sync.Map), |
36 | 33 | EtcdClient: new(etcd.EtcdClient), |
37 | - | |
38 | - TaskQueue: make([]chan func(), common.WorkerPoolSize), | |
39 | - } | |
40 | -} | |
41 | - | |
42 | -//StartWorkerPool 启动worker工作池 | |
43 | -func (s *Server) StartWorkerPool() { | |
44 | - //遍历需要启动worker的数量,依此启动 | |
45 | - for i := 0; i < s.SConf.WorkerPoolSize; i++ { | |
46 | - //一个worker被启动 | |
47 | - //给当前worker对应的任务队列开辟空间 | |
48 | - s.TaskQueue[i] = make(chan func(), common.MaxTaskPerWorker) | |
49 | - //启动当前Worker,阻塞的等待对应的任务队列是否有消息传递进来 | |
50 | - go s.StartOneWorker(i, s.TaskQueue[i]) | |
51 | - } | |
52 | -} | |
53 | - | |
54 | -//StartOneWorker 启动一个Worker工作流程 | |
55 | -func (s *Server) StartOneWorker(workerID int, taskQueue chan func()) { | |
56 | - //不断的等待队列中的消息 | |
57 | - for { | |
58 | - select { | |
59 | - //有消息则取出队列的Request,并执行绑定的业务方法 | |
60 | - case f:= <-taskQueue: | |
61 | - _ = workerID | |
62 | - f() | |
63 | - //s.DoMsgHandler(request) | |
64 | - } | |
65 | 34 | } |
66 | 35 | } |
67 | 36 | |
... | ... | @@ -131,9 +100,6 @@ func (s *Server)Start() error { |
131 | 100 | return err |
132 | 101 | } |
133 | 102 | |
134 | - //启动协程池 | |
135 | - s.StartWorkerPool() | |
136 | - | |
137 | 103 | //启动定时器 |
138 | 104 | s.handleTimeOut() |
139 | 105 | |
... | ... | @@ -154,5 +120,13 @@ func (s *Server)Start() error { |
154 | 120 | } |
155 | 121 | |
156 | 122 | func (s *Server)Stop() { |
157 | - TimeWheel.Stop() | |
123 | + timewheel.StopTimer() | |
124 | + | |
125 | + s.Clients.Range(func(key, value interface{}) bool { | |
126 | + client := value.(*Connection) | |
127 | + client.Stop() | |
128 | + return true | |
129 | + }) | |
130 | + | |
131 | + db.MongoClient.Disconnect(context.TODO()) | |
158 | 132 | } |
159 | 133 | \ No newline at end of file | ... | ... |
src/components/timewheel/timerwheel.go
... | ... | @@ -83,7 +83,7 @@ func NewTimeWheel() *TimeWheel { |
83 | 83 | tick: 10*time.Millisecond, |
84 | 84 | time: 0, |
85 | 85 | WorkPool: workpool.NewWorkPool(common.WorkerPoolSize, common.MaxTaskPerWorker), |
86 | - exit: nil, | |
86 | + exit: make(chan struct{}), | |
87 | 87 | } |
88 | 88 | for i :=0; i < TimeNear; i++ { |
89 | 89 | tw.near[i] = newBucket() |
... | ... | @@ -198,4 +198,8 @@ func (tw *TimeWheel) afterFunc(expiration time.Duration, f func()) { |
198 | 198 | |
199 | 199 | func TimeOut(expire time.Duration, f func()) { |
200 | 200 | TimingWheel.afterFunc(expire, f) |
201 | +} | |
202 | + | |
203 | +func StopTimer() { | |
204 | + TimingWheel.Stop() | |
201 | 205 | } |
202 | 206 | \ No newline at end of file | ... | ... |
src/models/role.go
... | ... | @@ -99,10 +99,10 @@ func (m *RoleModel) AddHero(hero *pb.Hero) { |
99 | 99 | m.Heros[fmt.Sprintf("%s%s", m.Role.Id, h.Hero.Id)] = h |
100 | 100 | } |
101 | 101 | |
102 | -func (m *RoleModel) GetAllHero() map[string]*pb.Hero { | |
103 | - h := make(map[string]*pb.Hero) | |
104 | - for k, hero := range m.Heros { | |
105 | - h[k] = hero.Hero | |
102 | +func (m *RoleModel) GetAllHero() []*pb.Hero { | |
103 | + var h []*pb.Hero | |
104 | + for _, hero := range m.Heros { | |
105 | + h = append(h, hero.Hero) | |
106 | 106 | } |
107 | 107 | return h |
108 | 108 | } | ... | ... |
src/plugin/RolePlugin.go