Skip to content

Commit cc6acce

Browse files
authored
Merge pull request #26 from codeGROOVE-dev/star-org
move ping/pong to background
2 parents aa831d9 + f411327 commit cc6acce

2 files changed

Lines changed: 25 additions & 14 deletions

File tree

pkg/client/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,8 @@ func (c *Client) connect(ctx context.Context) error {
339339

340340
// Handle error response
341341
if responseType == "error" {
342-
errorCode, _ := firstResponse["error"].(string) //nolint:errcheck // type assertion, not error
343-
message, _ := firstResponse["message"].(string) //nolint:errcheck // type assertion, not error
342+
errorCode, _ := firstResponse["error"].(string) //nolint:errcheck // type assertion, not error
343+
message, _ := firstResponse["message"].(string) //nolint:errcheck // type assertion, not error
344344
c.logger.Error(separatorLine)
345345
c.logger.Error("SUBSCRIPTION REJECTED BY SERVER!", "error_code", errorCode, "message", message)
346346
c.logger.Error(separatorLine)

pkg/hub/client.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,12 @@ func NewClient(id string, sub Subscription, conn *websocket.Conn, hub *Hub, user
5959
// Run handles sending events to the client and periodic pings.
6060
// Context should be passed from the caller for proper lifecycle management.
6161
func (c *Client) Run(ctx context.Context, pingInterval, writeTimeout time.Duration) {
62-
ticker := time.NewTicker(pingInterval)
63-
defer func() {
64-
ticker.Stop()
65-
// Don't close the websocket here - let the main handler do it
66-
// This prevents double-close errors
67-
c.Close()
68-
}()
62+
defer c.Close()
63+
64+
// Start ping sender in separate goroutine to prevent event sends from blocking pings
65+
go c.sendPings(ctx, pingInterval, writeTimeout)
6966

67+
// Handle event sending in main goroutine
7068
for {
7169
select {
7270
case <-ctx.Done():
@@ -104,6 +102,24 @@ func (c *Client) Run(ctx context.Context, pingInterval, writeTimeout time.Durati
104102

105103
log.Printf("✓ Event sent to client %s", c.ID)
106104

105+
case <-c.done:
106+
log.Printf("client %s: done signal received", c.ID)
107+
return
108+
}
109+
}
110+
}
111+
112+
// sendPings sends periodic pings in a separate goroutine to prevent blocking by event sends.
113+
func (c *Client) sendPings(ctx context.Context, pingInterval, writeTimeout time.Duration) {
114+
ticker := time.NewTicker(pingInterval)
115+
defer ticker.Stop()
116+
117+
for {
118+
select {
119+
case <-ctx.Done():
120+
return
121+
case <-c.done:
122+
return
107123
case <-ticker.C:
108124
// Check if we're missing pongs before sending next ping
109125
c.mu.RLock()
@@ -139,11 +155,6 @@ func (c *Client) Run(ctx context.Context, pingInterval, writeTimeout time.Durati
139155
log.Printf("error sending ping to client %s: %v", c.ID, err)
140156
return
141157
}
142-
// Ping sent to keep connection alive
143-
144-
case <-c.done:
145-
log.Printf("client %s: done signal received", c.ID)
146-
return
147158
}
148159
}
149160
}

0 commit comments

Comments
 (0)