mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-02 00:11:56 +03:00
reworked hub
This commit is contained in:
+57
-52
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user