fix issues
This commit is contained in:
@@ -5,6 +5,7 @@ package ultrabeam
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
@@ -12,6 +13,17 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Connection tuning. Remote operation (the antenna controller reached over the
|
||||
// internet, not the LAN) sees real latency and jitter, so the read timeout is
|
||||
// generous and a few transient timeouts are tolerated before the link is torn
|
||||
// down — otherwise a single slow reply dropped the whole connection and the
|
||||
// client churned reconnect/disconnect.
|
||||
const (
|
||||
ubReadTimeout = 4 * time.Second // was 1s — too tight for a remote link
|
||||
ubKeepAlive = 15 * time.Second // OS-level TCP keepalive
|
||||
ubMaxPollTimeout = 3 // consecutive read timeouts tolerated before reconnecting
|
||||
)
|
||||
|
||||
// Protocol constants
|
||||
const (
|
||||
STX byte = 0xF5 // 245 decimal
|
||||
@@ -110,6 +122,7 @@ func (c *Client) pollLoop() {
|
||||
defer ticker.Stop()
|
||||
|
||||
pollCount := 0
|
||||
pollFails := 0 // consecutive failed status polls (transient timeouts tolerated)
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -120,7 +133,8 @@ func (c *Client) pollLoop() {
|
||||
c.connMu.Lock()
|
||||
if c.conn == nil {
|
||||
log.Printf("Ultrabeam: Not connected, attempting connection...")
|
||||
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", c.host, c.port), 5*time.Second)
|
||||
dialer := net.Dialer{Timeout: 5 * time.Second, KeepAlive: ubKeepAlive}
|
||||
conn, err := dialer.Dial("tcp", net.JoinHostPort(c.host, fmt.Sprintf("%d", c.port)))
|
||||
if err != nil {
|
||||
log.Printf("Ultrabeam: Connection failed: %v", err)
|
||||
c.connMu.Unlock()
|
||||
@@ -133,6 +147,7 @@ func (c *Client) pollLoop() {
|
||||
}
|
||||
c.conn = conn
|
||||
c.reader = bufio.NewReader(c.conn)
|
||||
pollFails = 0
|
||||
log.Printf("Ultrabeam: Connected to %s:%d", c.host, c.port)
|
||||
}
|
||||
c.connMu.Unlock()
|
||||
@@ -140,8 +155,17 @@ func (c *Client) pollLoop() {
|
||||
// Query status
|
||||
status, err := c.queryStatus()
|
||||
if err != nil {
|
||||
log.Printf("Ultrabeam: Failed to query status: %v", err)
|
||||
// Close connection and retry
|
||||
// A single slow/lost reply over a remote link is normal — keep
|
||||
// the connection (and the last status) for a few tries before
|
||||
// tearing it down, so we don't churn reconnect/disconnect.
|
||||
var ne net.Error
|
||||
transient := errors.As(err, &ne) && ne.Timeout()
|
||||
pollFails++
|
||||
if transient && pollFails < ubMaxPollTimeout {
|
||||
log.Printf("Ultrabeam: status timeout (%d/%d), keeping link: %v", pollFails, ubMaxPollTimeout, err)
|
||||
continue
|
||||
}
|
||||
log.Printf("Ultrabeam: Failed to query status, reconnecting: %v", err)
|
||||
c.connMu.Lock()
|
||||
if c.conn != nil {
|
||||
c.conn.Close()
|
||||
@@ -156,6 +180,7 @@ func (c *Client) pollLoop() {
|
||||
c.statusMu.Unlock()
|
||||
continue
|
||||
}
|
||||
pollFails = 0
|
||||
|
||||
// Mark as connected
|
||||
status.Connected = true
|
||||
@@ -318,8 +343,8 @@ func (c *Client) sendCommand(cmd byte, data []byte) ([]byte, error) {
|
||||
return nil, fmt.Errorf("failed to write: %w", err)
|
||||
}
|
||||
|
||||
// Read reply with timeout
|
||||
c.conn.SetReadDeadline(time.Now().Add(1 * time.Second)) // Reduced from 2s to 1s
|
||||
// Read reply with timeout (generous — tolerates remote-link latency).
|
||||
c.conn.SetReadDeadline(time.Now().Add(ubReadTimeout))
|
||||
|
||||
// Read until we get a complete packet
|
||||
var buffer []byte
|
||||
|
||||
Reference in New Issue
Block a user