diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2024-07-09 21:36:27 -0700 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2024-07-09 21:42:05 -0700 |
| commit | d9bc63a10d0978d9a5222cf7be74044e55f409b7 (patch) | |
| tree | 1797c9593c279bf1334ed8285de8054a92a28dcb /hotline/client_manager.go | |
| parent | 8fa166777cbcd92e871e937d9557f0f1a732c04d (diff) | |
Extensive refactor and clean up
Diffstat (limited to 'hotline/client_manager.go')
| -rw-r--r-- | hotline/client_manager.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/hotline/client_manager.go b/hotline/client_manager.go new file mode 100644 index 0000000..ab6372c --- /dev/null +++ b/hotline/client_manager.go @@ -0,0 +1,99 @@ +package hotline + +import ( + "cmp" + "encoding/binary" + "github.com/stretchr/testify/mock" + "slices" + "sync" + "sync/atomic" +) + +type ClientID [2]byte + +type ClientManager interface { + List() []*ClientConn // Returns list of sorted clients + Get(id ClientID) *ClientConn + Add(cc *ClientConn) + Delete(id ClientID) +} + +type MockClientMgr struct { + mock.Mock +} + +func (m *MockClientMgr) List() []*ClientConn { + args := m.Called() + + return args.Get(0).([]*ClientConn) +} + +func (m *MockClientMgr) Get(id ClientID) *ClientConn { + args := m.Called(id) + + return args.Get(0).(*ClientConn) +} + +func (m *MockClientMgr) Add(cc *ClientConn) { + m.Called(cc) +} +func (m *MockClientMgr) Delete(id ClientID) { + m.Called(id) +} + +type MemClientMgr struct { + clients map[ClientID]*ClientConn + + mu sync.Mutex + nextClientID atomic.Uint32 +} + +func NewMemClientMgr() *MemClientMgr { + return &MemClientMgr{ + clients: make(map[ClientID]*ClientConn), + } +} + +// List returns slice of sorted clients. +func (cm *MemClientMgr) List() []*ClientConn { + cm.mu.Lock() + defer cm.mu.Unlock() + + var clients []*ClientConn + for _, client := range cm.clients { + clients = append(clients, client) + } + + slices.SortFunc(clients, func(a, b *ClientConn) int { + return cmp.Compare( + binary.BigEndian.Uint16(a.ID[:]), + binary.BigEndian.Uint16(b.ID[:]), + ) + }) + + return clients +} + +func (cm *MemClientMgr) Get(id ClientID) *ClientConn { + cm.mu.Lock() + defer cm.mu.Unlock() + + return cm.clients[id] +} + +func (cm *MemClientMgr) Add(cc *ClientConn) { + cm.mu.Lock() + defer cm.mu.Unlock() + + cm.nextClientID.Add(1) + binary.BigEndian.PutUint16(cc.ID[:], uint16(cm.nextClientID.Load())) + + cm.clients[cc.ID] = cc +} + +func (cm *MemClientMgr) Delete(id ClientID) { + cm.mu.Lock() + defer cm.mu.Unlock() + + delete(cm.clients, id) +} |