mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 12:34:02 +03:00
reworked hub
This commit is contained in:
+38
-26
@@ -1,48 +1,60 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
"github.com/9seconds/mtg/protocol"
|
||||
)
|
||||
|
||||
type Concentrator struct {
|
||||
hubs sync.Map
|
||||
type hub struct {
|
||||
subs map[string]*connectionHub
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (c *Concentrator) Write(packet conntypes.Packet, req *protocol.TelegramRequest) error {
|
||||
hub := c.getHub(req)
|
||||
connectionChan := make(chan *connection)
|
||||
hub.connectionRequestsChan <- &connectionHubRequest{
|
||||
req: req,
|
||||
responseChan: connectionChan,
|
||||
func (h *hub) Write(packet conntypes.Packet, req *protocol.TelegramRequest) error {
|
||||
sub := h.getHub(req)
|
||||
connections := make(chan *connection)
|
||||
sub.channelConnectionRequests <- &connectionHubRequest{
|
||||
request: req,
|
||||
response: connections,
|
||||
}
|
||||
|
||||
conn, ok := <-connectionChan
|
||||
conn, ok := <-connections
|
||||
if !ok {
|
||||
return errors.New("cannot establish connection to telegram")
|
||||
return ErrCannotCreateConnection
|
||||
}
|
||||
|
||||
if err := conn.write(packet); err != nil {
|
||||
return fmt.Errorf("cannot send packet: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Concentrator) getHub(req *protocol.TelegramRequest) *connectionHub {
|
||||
dcMapRaw, ok := c.hubs.Load(req.ClientProtocol.DC())
|
||||
if !ok {
|
||||
dcMapRaw, _ = c.hubs.LoadOrStore(req.ClientProtocol.DC(), &sync.Map{})
|
||||
}
|
||||
dcMap := dcMapRaw.(*sync.Map)
|
||||
func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
|
||||
keyBuilder := strings.Builder{}
|
||||
binary.Write(&keyBuilder, binary.LittleEndian, int16(req.ClientProtocol.DC()))
|
||||
keyBuilder.WriteRune('_')
|
||||
binary.Write(&keyBuilder, binary.LittleEndian, uint8(req.ClientProtocol.ConnectionProtocol()))
|
||||
key := keyBuilder.String()
|
||||
|
||||
h.mutex.RLock()
|
||||
rv, ok := h.subs[key]
|
||||
h.mutex.RUnlock()
|
||||
|
||||
loaded := true
|
||||
hubRaw, ok := dcMap.Load(req.ClientProtocol.ConnectionProtocol())
|
||||
if !ok {
|
||||
hubRaw, loaded = dcMap.LoadOrStore(req.ClientProtocol.ConnectionProtocol(),
|
||||
newConnectionHub())
|
||||
}
|
||||
hub := hubRaw.(*connectionHub)
|
||||
if !loaded {
|
||||
go hub.run()
|
||||
h.mutex.Lock()
|
||||
defer h.mutex.Unlock()
|
||||
|
||||
rv, ok = h.subs[key]
|
||||
if !ok {
|
||||
rv = newConnectionHub()
|
||||
h.subs[key] = rv
|
||||
}
|
||||
}
|
||||
|
||||
return hub
|
||||
return rv
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user