fix(transport): serialise graceful websocket close

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-03-31 13:42:04 +00:00 committed by Snider
parent 9523bd1e9a
commit 314c8ed470

View file

@ -482,9 +482,9 @@ func (t *Transport) Send(peerID string, msg *Message) error {
return pc.Send(msg)
}
// for pc := range transport.Connections() {
// _ = pc
// }
// for pc := range transport.Connections() {
// _ = pc
// }
func (t *Transport) Connections() iter.Seq[*PeerConnection] {
return func(yield func(*PeerConnection) bool) {
t.mutex.RLock()
@ -953,6 +953,10 @@ func (pc *PeerConnection) Send(msg *Message) error {
pc.writeMutex.Lock()
defer pc.writeMutex.Unlock()
return pc.sendLocked(msg)
}
func (pc *PeerConnection) sendLocked(msg *Message) error {
data, err := pc.transport.encryptMessage(msg, pc.SharedSecret)
if err != nil {
return err
@ -996,10 +1000,10 @@ const (
func (pc *PeerConnection) GracefulClose(reason string, code int) error {
var err error
pc.closeOnce.Do(func() {
pc.writeMutex.Lock()
defer pc.writeMutex.Unlock()
// Try to send disconnect message (best effort).
// Note: we must NOT call SetWriteDeadline outside writeMutex — Send()
// already manages write deadlines under the lock. Setting it here
// without the lock races with concurrent Send() calls (P2P-RACE-1).
if pc.transport != nil && pc.SharedSecret != nil {
identity := pc.transport.nodeManager.GetIdentity()
if identity != nil {
@ -1009,7 +1013,7 @@ func (pc *PeerConnection) GracefulClose(reason string, code int) error {
}
msg, msgErr := NewMessage(MessageDisconnect, identity.ID, pc.Peer.ID, payload)
if msgErr == nil {
pc.Send(msg)
_ = pc.sendLocked(msg)
}
}
}