fix: Save and close taking time when Flex or Icom is not connected
This commit is contained in:
+32
-4
@@ -3,6 +3,7 @@
|
||||
package cat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
@@ -27,9 +28,10 @@ type TCI struct {
|
||||
digitalDefault string // surfaced when the rig reports a digital mode (FT8/…)
|
||||
spotsEnabled bool // mirror cluster spots onto the TCI panorama
|
||||
|
||||
mu sync.Mutex // guards conn + writes + state
|
||||
conn *websocket.Conn
|
||||
ready bool
|
||||
mu sync.Mutex // guards conn + writes + state
|
||||
conn *websocket.Conn
|
||||
dialCancel context.CancelFunc // cancels an in-flight Connect dial (Interrupt/Stop)
|
||||
ready bool
|
||||
|
||||
// Cached state pushed by the radio.
|
||||
device string
|
||||
@@ -70,8 +72,18 @@ func (t *TCI) Connect() error {
|
||||
return fmt.Errorf("tci: no host configured")
|
||||
}
|
||||
url := fmt.Sprintf("ws://%s", net.JoinHostPort(host, strconv.Itoa(port)))
|
||||
// Cancellable dial so Interrupt() (Stop / Settings "Save & Close") aborts it at
|
||||
// once instead of waiting out a dead server's 5 s handshake timeout.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
t.mu.Lock()
|
||||
t.dialCancel = cancel
|
||||
t.mu.Unlock()
|
||||
dialer := websocket.Dialer{HandshakeTimeout: 5 * time.Second}
|
||||
conn, _, err := dialer.Dial(url, nil)
|
||||
conn, _, err := dialer.DialContext(ctx, url, nil)
|
||||
cancel()
|
||||
t.mu.Lock()
|
||||
t.dialCancel = nil
|
||||
t.mu.Unlock()
|
||||
if err != nil {
|
||||
return fmt.Errorf("tci: connect %s: %w", url, err)
|
||||
}
|
||||
@@ -122,6 +134,22 @@ func (t *TCI) Disconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt aborts an in-flight Connect dial so Stop()/Start() don't block on a
|
||||
// dead server's handshake timeout. Satisfies the Manager's interruptible
|
||||
// interface. Safe from another goroutine; a no-op when not dialing.
|
||||
func (t *TCI) Interrupt() {
|
||||
t.mu.Lock()
|
||||
cancel := t.dialCancel
|
||||
c := t.conn
|
||||
t.mu.Unlock()
|
||||
if cancel != nil {
|
||||
cancel()
|
||||
}
|
||||
if c != nil {
|
||||
_ = c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// ReadState returns the cached state pushed by the radio.
|
||||
func (t *TCI) ReadState() (RigState, error) {
|
||||
t.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user