reworked hub

This commit is contained in:
9seconds
2019-10-07 17:26:03 +03:00
parent c9743b5675
commit 413cafeeb6
7 changed files with 189 additions and 148 deletions
+57 -52
View File
@@ -1,84 +1,89 @@
package hub
import "time"
import (
"time"
"github.com/9seconds/mtg/protocol"
)
const hubGCEvery = time.Minute
type connectionHub struct {
sockets map[connectionID]*connection
brokenSocketsChan chan connectionID
connectionRequestsChan chan *connectionHubRequest
returnConnectionsChan chan *connection
type connectionHubRequest struct {
request *protocol.TelegramRequest
response chan<- *connection
}
func (h *connectionHub) run() {
gcTicker := time.NewTicker(hubGCEvery)
defer gcTicker.Stop()
type connectionHub struct {
sockets map[int]*connection
channelBrokenSockets chan int
channelConnectionRequests chan *connectionHubRequest
channelReturnConnections chan *connection
}
func (c *connectionHub) run() {
ticker := time.NewTicker(hubGCEvery)
defer ticker.Stop()
for {
select {
case <-gcTicker.C:
h.runGC()
case id := <-h.brokenSocketsChan:
h.runBrokenConnection(id)
case request := <-h.connectionRequestsChan:
h.runConnectionRequest(request)
case conn := <-h.returnConnectionsChan:
h.runReturnConnection(conn)
case <-ticker.C:
c.runGC()
case request := <-c.channelConnectionRequests:
c.runConnectionRequest(request)
case id := <-c.channelBrokenSockets:
c.runBrokenSocket(id)
case conn := <-c.channelReturnConnections:
c.runReturnConnection(conn)
}
}
}
func (h *connectionHub) runBrokenConnection(id connectionID) {
delete(h.sockets, id)
}
func (h *connectionHub) runGC() {
for key, conn := range h.sockets {
closing, pending := conn.Stats()
func (c *connectionHub) runGC() {
for key, conn := range c.sockets {
switch {
case closing:
delete(h.sockets, key)
case pending == 0:
conn.Close()
delete(h.sockets, key)
case conn.closed():
delete(c.sockets, key)
case conn.idle():
conn.shutdown()
delete(c.sockets, key)
return
}
}
}
func (h *connectionHub) runConnectionRequest(req *connectionHubRequest) {
for key, conn := range h.sockets {
closing, _ := conn.Stats()
delete(h.sockets, key)
if !closing {
req.responseChan <- conn
func (c *connectionHub) runConnectionRequest(req *connectionHubRequest) {
for key, conn := range c.sockets {
delete(c.sockets, key)
if !conn.closed() {
req.response <- conn
close(req.response)
return
}
}
newConn, err := newConnection(h, req.req)
if err != nil {
close(req.responseChan)
return
if conn, err := newConnection(req.request, c); err == nil {
req.response <- conn
}
req.responseChan <- newConn
close(req.response)
}
func (h *connectionHub) runReturnConnection(conn *connection) {
h.sockets[conn.id] = conn
func (c *connectionHub) runBrokenSocket(id int) {
delete(c.sockets, id)
}
func (c *connectionHub) runReturnConnection(conn *connection) {
c.sockets[conn.id] = conn
}
func newConnectionHub() *connectionHub {
return &connectionHub{
sockets: map[connectionID]*connection{},
brokenSocketsChan: make(chan connectionID, 1),
connectionRequestsChan: make(chan *connectionHubRequest),
returnConnectionsChan: make(chan *connection, 1),
rv := &connectionHub{
sockets: map[int]*connection{},
channelBrokenSockets: make(chan int, 1),
channelConnectionRequests: make(chan *connectionHubRequest),
channelReturnConnections: make(chan *connection, 1),
}
go rv.run()
return rv
}