Files
ionscale/internal/broker/broker.go
T
Johan Siebens 5ad89ff02f initial working version
Signed-off-by: Johan Siebens <johan.siebens@gmail.com>
2022-05-09 21:54:06 +02:00

103 lines
1.8 KiB
Go

package broker
import (
"sync"
"tailscale.com/types/key"
)
type BrokerPool struct {
lock sync.Mutex
store map[uint64]Broker
}
type Signal struct {
PeerUpdated *uint64
PeersRemoved []uint64
}
type Broker interface {
AddClient(*Client)
RemoveClient(uint64)
SignalPeerUpdated(id uint64)
SignalPeersRemoved([]uint64)
IsConnected(uint64) bool
}
func NewBrokerPool() *BrokerPool {
return &BrokerPool{
store: make(map[uint64]Broker),
}
}
func (m *BrokerPool) Get(tailnetID uint64) Broker {
m.lock.Lock()
defer m.lock.Unlock()
b, ok := m.store[tailnetID]
if !ok {
b = newBroker(tailnetID)
m.store[tailnetID] = b
}
return b
}
func newBroker(tailnetID uint64) Broker {
b := &broker{
tailnetID: tailnetID,
newClients: make(chan *Client),
closingClients: make(chan uint64),
clients: make(map[uint64]*Client),
signalChannel: make(chan *Signal),
}
go b.listen()
return b
}
type broker struct {
tailnetID uint64
privateKey *key.MachinePrivate
newClients chan *Client
closingClients chan uint64
signalChannel chan *Signal
clients map[uint64]*Client
}
func (h *broker) IsConnected(id uint64) (ok bool) {
_, ok = h.clients[id]
return
}
func (h *broker) AddClient(client *Client) {
h.newClients <- client
}
func (h *broker) RemoveClient(id uint64) {
h.closingClients <- id
}
func (h *broker) SignalPeerUpdated(id uint64) {
h.signalChannel <- &Signal{PeerUpdated: &id}
}
func (h *broker) SignalPeersRemoved(ids []uint64) {
h.signalChannel <- &Signal{PeersRemoved: ids}
}
func (h *broker) listen() {
for {
select {
case s := <-h.newClients:
h.clients[s.id] = s
case s := <-h.closingClients:
delete(h.clients, s)
case s := <-h.signalChannel:
for _, c := range h.clients {
c.SignalUpdate(s)
}
}
}
}