Skip to content

Commit

Permalink
Merge pull request #7038 from onflow/illia-malachyn/7036-ws-controlle…
Browse files Browse the repository at this point in the history
…r-should-recover-from-panics

[Access] ws controller should recover from panics
  • Loading branch information
peterargue authored Feb 25, 2025
2 parents 806075e + f8d1af9 commit 4fe32ac
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions engine/access/rest/websockets/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ func (c *Controller) configureKeepalive() error {
// keepalive sends a ping message periodically to keep the WebSocket connection alive
// and avoid timeouts.
func (c *Controller) keepalive(ctx context.Context) error {
defer func() {
// gracefully handle panics from github.com/gorilla/websocket
if r := recover(); r != nil {
c.logger.Warn().Interface("recovered_context", r).Msg("keepalive routine recovered from panic")
}
}()

pingTicker := time.NewTicker(PingPeriod)
defer pingTicker.Stop()

Expand All @@ -246,10 +253,12 @@ func (c *Controller) keepalive(ctx context.Context) error {
// If no messages are sent within InactivityTimeout and no active data providers exist,
// the connection will be closed.
func (c *Controller) writeMessages(ctx context.Context) error {
inactivityTicker := time.NewTicker(c.inactivityTickerPeriod())
defer inactivityTicker.Stop()

lastMessageSentAt := time.Now()
defer func() {
// gracefully handle panics from github.com/gorilla/websocket
if r := recover(); r != nil {
c.logger.Warn().Interface("recovered_context", r).Msg("writer routine recovered from panic")
}
}()

defer func() {
// drain the channel as some providers may still send data to it after this routine shutdowns
Expand All @@ -260,6 +269,11 @@ func (c *Controller) writeMessages(ctx context.Context) error {
}()
}()

inactivityTicker := time.NewTicker(c.inactivityTickerPeriod())
defer inactivityTicker.Stop()

lastMessageSentAt := time.Now()

for {
select {
case <-ctx.Done():
Expand Down Expand Up @@ -308,6 +322,13 @@ func (c *Controller) inactivityTickerPeriod() time.Duration {
// readMessages continuously reads messages from a client WebSocket connection,
// validates each message, and processes it based on the message type.
func (c *Controller) readMessages(ctx context.Context) error {
defer func() {
// gracefully handle panics from github.com/gorilla/websocket
if r := recover(); r != nil {
c.logger.Warn().Interface("recovered_context", r).Msg("reader routine recovered from panic")
}
}()

for {
var message json.RawMessage
if err := c.conn.ReadJSON(&message); err != nil {
Expand Down

0 comments on commit 4fe32ac

Please sign in to comment.