FILE / ScuroNeko/mtg

hub/mux.go

Исходный файл и его история в репозитории.
FILE 33b1a5426cf421ab93ce34ee024176a33db806b3
Files
mtg/hub/mux.go
T
2019-11-19 11:55:33 +03:00

91 lines
1.6 KiB
Go

package hub
import (
"context"
"time"
"github.com/9seconds/mtg/conntypes"
"github.com/9seconds/mtg/protocol"
)
const muxGCEvery = time.Minute
type muxNewRequest struct {
req *protocol.TelegramRequest
resp chan<- muxNewResponse
}
type muxNewResponse struct {
conn *ProxyConn
err error
}
type mux struct {
connections connectionList
clients map[string]*connection
ctx context.Context
channelClosed chan conntypes.ConnID
channelNew chan muxNewRequest
}
func (m *mux) run() {
gcTicker := time.NewTicker(muxGCEvery)
defer gcTicker.Stop()
for {
select {
case <-m.ctx.Done():
for _, v := range m.clients {
v.Close()
}
return
case <-gcTicker.C:
m.connections.gc()
case req := <-m.channelNew:
m.connections.gc()
proxyConn := newProxyConn(req.req, m.channelClosed)
conn, err := m.connections.get(proxyConn)
if err == nil {
m.clients[string(req.req.ConnID[:])] = conn
}
req.resp <- muxNewResponse{
conn: proxyConn,
err: err,
}
close(req.resp)
case connID := <-m.channelClosed:
if conn, ok := m.clients[string(connID[:])]; ok {
conn.Detach(connID)
delete(m.clients, string(connID[:]))
}
}
}
}
func (m *mux) Get(req *protocol.TelegramRequest) (*ProxyConn, error) {
resp := make(chan muxNewResponse)
m.channelNew <- muxNewRequest{
req: req,
resp: resp,
}
rv := <-resp
return rv.conn, rv.err
}
func newMux(ctx context.Context) *mux {
m := &mux{
ctx: ctx,
clients: make(map[string]*connection),
channelClosed: make(chan conntypes.ConnID, 1),
channelNew: make(chan muxNewRequest),
}
go m.run()
return m
}