Files
go-cart-actor/packet-queue.go
matst80 98d9b2451e
Some checks failed
Build and Publish / BuildAndDeployAmd64 (push) Failing after 27s
Build and Publish / BuildAndDeploy (push) Successful in 2m19s
use persistent connections
2024-11-12 17:09:46 +01:00

110 lines
2.2 KiB
Go

package main
import (
"bufio"
"fmt"
"log"
"sync"
)
type PacketQueue struct {
mu sync.RWMutex
expectedPackages map[uint32]*Listener
}
type CallResult struct {
StatusCode uint32
Data []byte
}
type Listener struct {
Count int
Chan chan CallResult
}
func NewPacketQueue(connection *PersistentConnection) *PacketQueue {
queue := &PacketQueue{
expectedPackages: make(map[uint32]*Listener),
}
go queue.HandleConnection(connection)
return queue
}
func (p *PacketQueue) RemoveListeners() {
p.mu.Lock()
defer p.mu.Unlock()
for _, l := range p.expectedPackages {
close(l.Chan)
}
p.expectedPackages = make(map[uint32]*Listener)
}
func (p *PacketQueue) HandleConnection(connection *PersistentConnection) error {
defer connection.Close()
defer p.RemoveListeners()
var packet Packet
reader := bufio.NewReader(connection)
for {
err := ReadPacket(reader, &packet)
if err != nil {
return connection.HandleConnectionError(err)
}
if packet.Version != CurrentPacketVersion {
log.Printf("Incorrect packet version: %v\n", packet.Version)
return connection.HandleConnectionError(fmt.Errorf("incorrect packet version: %d", packet.Version))
}
if packet.DataLength == 0 {
go p.HandleData(packet.MessageType, CallResult{
StatusCode: packet.StatusCode,
Data: []byte{},
})
continue
}
data, err := GetPacketData(reader, packet.DataLength)
if err != nil {
log.Printf("Error receiving packet data: %v\n", err)
return connection.HandleConnectionError(err)
} else {
go p.HandleData(packet.MessageType, CallResult{
StatusCode: packet.StatusCode,
Data: data,
})
}
}
}
func (p *PacketQueue) HandleData(t uint32, data CallResult) {
p.mu.Lock()
defer p.mu.Unlock()
l, ok := p.expectedPackages[t]
if ok {
l.Chan <- data
l.Count--
if l.Count == 0 {
close(l.Chan)
delete(p.expectedPackages, t)
}
return
}
}
func (p *PacketQueue) Expect(messageType uint32) <-chan CallResult {
p.mu.Lock()
defer p.mu.Unlock()
l, ok := p.expectedPackages[messageType]
if ok {
l.Count++
return l.Chan
}
ch := make(chan CallResult)
p.expectedPackages[messageType] = &Listener{
Count: 1,
Chan: ch,
}
return ch
}