Files
go-cart-actor/tcp-cart-client.go
matst80 9f7c8227c2
All checks were successful
Build and Publish / BuildAndDeployAmd64 (push) Successful in 29s
Build and Publish / BuildAndDeploy (push) Successful in 2m25s
craps
2024-11-13 20:16:40 +01:00

97 lines
2.3 KiB
Go

package main
import (
"encoding/binary"
"log"
"sync"
)
type CartClient struct {
*CartTCPClient
}
func CartDial(address string) (*CartClient, error) {
mux, err := NewCartTCPClient(address)
if err != nil {
return nil, err
}
client := &CartClient{
CartTCPClient: mux,
}
return client, nil
}
func (c *Client) Close() {
log.Printf("Closing connection to %s\n", c.PersistentConnection.address)
c.PersistentConnection.Close()
}
type CartTCPClient struct {
PersistentConnection *PersistentConnection
sendMux sync.Mutex
ErrorCount int
address string
*CartPacketQueue
}
func NewCartTCPClient(address string) (*CartTCPClient, error) {
connection, err := NewPersistentConnection(address)
if err != nil {
return nil, err
}
return &CartTCPClient{
ErrorCount: 0,
PersistentConnection: connection,
address: address,
CartPacketQueue: NewCartPacketQueue(connection),
}, nil
}
func (m *CartTCPClient) SendPacket(messageType CartMessage, id CartId, data []byte) error {
m.sendMux.Lock()
defer m.sendMux.Unlock()
m.PersistentConnection.Conn.Write(header[:])
err := binary.Write(m.PersistentConnection, binary.LittleEndian, CartPacket{
Version: CurrentPacketVersion,
MessageType: messageType,
DataLength: uint32(len(data)),
Id: id,
})
if err != nil {
return m.PersistentConnection.HandleConnectionError(err)
}
_, err = m.PersistentConnection.Write(data)
return m.PersistentConnection.HandleConnectionError(err)
}
func (m *CartTCPClient) call(messageType CartMessage, id CartId, responseType CartMessage, data []byte) (*CallResult, error) {
packetChan := m.Expect(responseType, id)
err := m.SendPacket(messageType, id, data)
if err != nil {
return nil, m.PersistentConnection.HandleConnectionError(err)
}
ret := <-packetChan
return &ret, nil
}
func isRetirableError(err error) bool {
log.Printf("is retryable error: %v", err)
return false
}
func (m *CartTCPClient) Call(messageType CartMessage, id CartId, responseType CartMessage, data []byte) (*CallResult, error) {
retries := 0
result, err := m.call(messageType, id, responseType, data)
for err != nil && retries < 3 {
if !isRetirableError(err) {
break
}
retries++
log.Printf("Retrying call to %d\n", messageType)
result, err = m.call(messageType, id, responseType, data)
}
return result, err
}