diff --git a/client/main.go b/client/main.go index 6c71614..d5bbb2e 100644 --- a/client/main.go +++ b/client/main.go @@ -15,7 +15,7 @@ import ( "github.com/sqlrsync/sqlrsync.com/sync" ) -var VERSION = "0.0.8" +var VERSION = "0.0.9" var ( serverURL string verbose bool diff --git a/client/remote/client.go b/client/remote/client.go index c1ee4a6..4e1d997 100644 --- a/client/remote/client.go +++ b/client/remote/client.go @@ -1455,14 +1455,29 @@ func (c *Client) writeLoop() { err := conn.WriteMessage(websocket.BinaryMessage, data) if err != nil { c.logger.Error("WebSocket write error", zap.Error(err)) + + // If the error indicates we already sent a close, treat this as a normal + // closure for PUSH syncs and mark the sync completed so the caller can + // finish processing. This happens when the websocket library returns + // "websocket: close sent" while attempting to write after a close. + if strings.Contains(err.Error(), "close sent") { + c.logger.Info("Write error contains 'close sent' - treating as normal closure") + c.logger.Info("Ending PUSH sync due to close-sent write error") + c.setSyncCompleted(true) + } c.setError(err) c.setConnected(false) - // Signal potential reconnection - select { - case c.reconnectChan <- struct{}{}: - default: - } + // Treat this as a true disconnection (do not trigger reconnect). + // Close the read queue so any readers observe EOF and stop. + func() { + defer func() { + if r := recover(); r != nil { + // ignore if already closed + } + }() + close(c.readQueue) + }() return } diff --git a/client/sync/coordinator.go b/client/sync/coordinator.go index 4c40637..6151280 100644 --- a/client/sync/coordinator.go +++ b/client/sync/coordinator.go @@ -361,7 +361,7 @@ func (c *Coordinator) executePull(isSubscription bool) error { AuthKey: authResult.AccessKey, ReplicaID: authResult.ReplicaID, Timeout: 8000, - PingPong: false, // No ping/pong needed for single sync + PingPong: true, // Ping/pong enabled for subscription sync Logger: c.logger.Named("remote"), Subscribe: false, // Subscription handled separately EnableTrafficInspection: c.config.Verbose,