@@ -67,7 +67,7 @@ type sessionWS struct {
67
67
runtime * Runtime
68
68
69
69
stopped bool
70
- closeSent * atomic.Bool
70
+ closeSentCAS * atomic.Uint32
71
71
closeWaitCh chan struct {}
72
72
conn * websocket.Conn
73
73
receivedMessageCounter int
@@ -122,6 +122,8 @@ func NewSessionWS(logger *zap.Logger, config Config, format SessionFormat, sessi
122
122
runtime : runtime ,
123
123
124
124
stopped : false ,
125
+ closeSentCAS : atomic .NewUint32 (0 ),
126
+ closeWaitCh : make (chan struct {}),
125
127
conn : conn ,
126
128
receivedMessageCounter : config .GetSocket ().PingBackoffThreshold ,
127
129
pingTimer : time .NewTimer (time .Duration (config .GetSocket ().PingPeriodMs ) * time .Millisecond ),
@@ -190,15 +192,12 @@ func (s *sessionWS) Consume() {
190
192
s .maybeResetPingTimer ()
191
193
return nil
192
194
})
193
- s .closeSent = atomic .NewBool (false )
194
- s .closeWaitCh = make (chan struct {}, 1 )
195
- // Disable the close handler so that the server can handle the close message itself.
196
195
s .conn .SetCloseHandler (func (code int , text string ) error {
197
- if ! s . closeSent . Load ( ) {
196
+ if s . closeSentCAS . CompareAndSwap ( 0 , 1 ) {
198
197
message := websocket .FormatCloseMessage (code , "" )
199
198
_ = s .conn .WriteControl (websocket .CloseMessage , message , time .Now ().Add (s .pongWaitDuration ))
200
199
} else {
201
- s .closeWaitCh <- struct {}{}
200
+ close ( s .closeWaitCh )
202
201
}
203
202
return nil
204
203
})
@@ -525,20 +524,21 @@ func (s *sessionWS) Close(msg string, reason runtime.PresenceReason, envelopes .
525
524
}
526
525
527
526
if msg != "" {
528
- // Server initiated close, attempt to send a close control message.
529
- reasonMsg := websocket .FormatCloseMessage (websocket .CloseNormalClosure , msg )
530
- if err := s .conn .WriteControl (websocket .CloseMessage , reasonMsg , time .Now ().Add (s .writeWaitDuration )); err != nil {
531
- // This may not be possible if the socket was already fully closed by an error.
532
- s .logger .Debug ("Could not send close message" , zap .Error (err ))
533
- } else {
534
- s .closeSent .Store (true )
535
- t := time .NewTimer (10 * time .Second )
536
- defer t .Stop ()
537
- select {
538
- case <- s .closeWaitCh :
539
- s .logger .Debug ("socket close ack received" )
540
- case <- t .C :
541
- s .logger .Debug ("socket close ack not received within 10 seconds" )
527
+ if s .closeSentCAS .CompareAndSwap (0 , 1 ) {
528
+ // Server initiated close, attempt to send a close control message.
529
+ reasonMsg := websocket .FormatCloseMessage (websocket .CloseNormalClosure , msg )
530
+ if err := s .conn .WriteControl (websocket .CloseMessage , reasonMsg , time .Now ().Add (s .writeWaitDuration )); err != nil {
531
+ // This may not be possible if the socket was already fully closed by an error.
532
+ s .logger .Debug ("Could not send close message" , zap .Error (err ))
533
+ } else {
534
+ t := time .NewTimer (10 * time .Second )
535
+ defer t .Stop ()
536
+ select {
537
+ case <- s .closeWaitCh :
538
+ s .logger .Debug ("socket close ack received" )
539
+ case <- t .C :
540
+ s .logger .Debug ("socket close ack not received within 10 seconds" )
541
+ }
542
542
}
543
543
}
544
544
}
0 commit comments