Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3176e10

Browse files
authored
fix: Use atomic value for logger in peer (#1257)
This caused many races where logs would escape the tests by milliseconds. By using an atomic on the logger, we can fix all of it!
1 parent e531c09 commit 3176e10

File tree

2 files changed

+40
-41
lines changed

2 files changed

+40
-41
lines changed

peer/channel.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ func (c *Channel) init() {
118118
}
119119
})
120120
c.dc.OnClose(func() {
121-
c.conn.opts.Logger.Debug(context.Background(), "datachannel closing from OnClose", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()))
121+
c.conn.logger().Debug(context.Background(), "datachannel closing from OnClose", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()))
122122
_ = c.closeWithError(ErrClosed)
123123
})
124124
c.dc.OnOpen(func() {
125125
c.closeMutex.Lock()
126126
defer c.closeMutex.Unlock()
127127

128-
c.conn.opts.Logger.Debug(context.Background(), "datachannel opening", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()))
128+
c.conn.logger().Debug(context.Background(), "datachannel opening", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()))
129129
var err error
130130
c.rwc, err = c.dc.Detach()
131131
if err != nil {
@@ -289,7 +289,7 @@ func (c *Channel) closeWithError(err error) error {
289289
return c.closeError
290290
}
291291

292-
c.conn.opts.Logger.Debug(context.Background(), "datachannel closing with error", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()), slog.Error(err))
292+
c.conn.logger().Debug(context.Background(), "datachannel closing with error", slog.F("id", c.dc.ID()), slog.F("label", c.dc.Label()), slog.Error(err))
293293
if err == nil {
294294
c.closeError = ErrClosed
295295
} else {

peer/conn.go

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
6363
conn := &Conn{
6464
pingChannelID: 1,
6565
pingEchoChannelID: 2,
66-
opts: opts,
6766
rtc: rtc,
6867
offerer: client,
6968
closed: make(chan struct{}),
@@ -75,7 +74,9 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
7574
localCandidateChannel: make(chan webrtc.ICECandidateInit),
7675
localSessionDescriptionChannel: make(chan webrtc.SessionDescription, 1),
7776
remoteSessionDescriptionChannel: make(chan webrtc.SessionDescription, 1),
77+
settingEngine: opts.SettingEngine,
7878
}
79+
conn.loggerValue.Store(opts.Logger)
7980
if client {
8081
// If we're the client, we want to flip the echo and
8182
// ping channel IDs so pings don't accidentally hit each other.
@@ -100,8 +101,7 @@ type ConnOptions struct {
100101
// This struct wraps webrtc.PeerConnection to add bidirectional pings,
101102
// concurrent-safe webrtc.DataChannel, and standardized errors for connection state.
102103
type Conn struct {
103-
rtc *webrtc.PeerConnection
104-
opts *ConnOptions
104+
rtc *webrtc.PeerConnection
105105
// Determines whether this connection will send the offer or the answer.
106106
offerer bool
107107

@@ -127,6 +127,9 @@ type Conn struct {
127127
negotiateMutex sync.Mutex
128128
hasNegotiated bool
129129

130+
loggerValue atomic.Value
131+
settingEngine webrtc.SettingEngine
132+
130133
pingChannelID uint16
131134
pingEchoChannelID uint16
132135

@@ -139,6 +142,14 @@ type Conn struct {
139142
pingError error
140143
}
141144

145+
func (c *Conn) logger() slog.Logger {
146+
log, valid := c.loggerValue.Load().(slog.Logger)
147+
if !valid {
148+
return slog.Logger{}
149+
}
150+
return log
151+
}
152+
142153
func (c *Conn) init() error {
143154
// The negotiation needed callback can take a little bit to execute!
144155
c.negotiateMutex.Lock()
@@ -152,7 +163,7 @@ func (c *Conn) init() error {
152163
// Don't log more state changes if we've already closed.
153164
return
154165
default:
155-
c.opts.Logger.Debug(context.Background(), "ice connection state updated",
166+
c.logger().Debug(context.Background(), "ice connection state updated",
156167
slog.F("state", iceConnectionState))
157168

158169
if iceConnectionState == webrtc.ICEConnectionStateClosed {
@@ -171,7 +182,7 @@ func (c *Conn) init() error {
171182
// Don't log more state changes if we've already closed.
172183
return
173184
default:
174-
c.opts.Logger.Debug(context.Background(), "ice gathering state updated",
185+
c.logger().Debug(context.Background(), "ice gathering state updated",
175186
slog.F("state", iceGatherState))
176187

177188
if iceGatherState == webrtc.ICEGathererStateClosed {
@@ -189,7 +200,7 @@ func (c *Conn) init() error {
189200
if c.isClosed() {
190201
return
191202
}
192-
c.opts.Logger.Debug(context.Background(), "rtc connection updated",
203+
c.logger().Debug(context.Background(), "rtc connection updated",
193204
slog.F("state", peerConnectionState))
194205
}()
195206

@@ -225,38 +236,25 @@ func (c *Conn) init() error {
225236
// These functions need to check if the conn is closed, because they can be
226237
// called after being closed.
227238
c.rtc.OnSignalingStateChange(func(signalState webrtc.SignalingState) {
228-
if c.isClosed() {
229-
return
230-
}
231-
c.opts.Logger.Debug(context.Background(), "signaling state updated",
239+
c.logger().Debug(context.Background(), "signaling state updated",
232240
slog.F("state", signalState))
233241
})
234242
c.rtc.SCTP().Transport().OnStateChange(func(dtlsTransportState webrtc.DTLSTransportState) {
235-
if c.isClosed() {
236-
return
237-
}
238-
c.opts.Logger.Debug(context.Background(), "dtls transport state updated",
243+
c.logger().Debug(context.Background(), "dtls transport state updated",
239244
slog.F("state", dtlsTransportState))
240245
})
241246
c.rtc.SCTP().Transport().ICETransport().OnSelectedCandidatePairChange(func(candidatePair *webrtc.ICECandidatePair) {
242-
if c.isClosed() {
243-
return
244-
}
245-
c.opts.Logger.Debug(context.Background(), "selected candidate pair changed",
247+
c.logger().Debug(context.Background(), "selected candidate pair changed",
246248
slog.F("local", candidatePair.Local), slog.F("remote", candidatePair.Remote))
247249
})
248250
c.rtc.OnICECandidate(func(iceCandidate *webrtc.ICECandidate) {
249-
if c.isClosed() {
250-
return
251-
}
252-
253251
if iceCandidate == nil {
254252
return
255253
}
256254
// Run this in a goroutine so we don't block pion/webrtc
257255
// from continuing.
258256
go func() {
259-
c.opts.Logger.Debug(context.Background(), "sending local candidate", slog.F("candidate", iceCandidate.ToJSON().Candidate))
257+
c.logger().Debug(context.Background(), "sending local candidate", slog.F("candidate", iceCandidate.ToJSON().Candidate))
260258
select {
261259
case <-c.closed:
262260
break
@@ -287,7 +285,7 @@ func (c *Conn) init() error {
287285
// negotiate is triggered when a connection is ready to be established.
288286
// See trickle ICE for the expected exchange: https://webrtchacks.com/trickle-ice/
289287
func (c *Conn) negotiate() {
290-
c.opts.Logger.Debug(context.Background(), "negotiating")
288+
c.logger().Debug(context.Background(), "negotiating")
291289
// ICE candidates cannot be added until SessionDescriptions have been
292290
// exchanged between peers.
293291
if c.hasNegotiated {
@@ -311,23 +309,23 @@ func (c *Conn) negotiate() {
311309
_ = c.CloseWithError(xerrors.Errorf("set local description: %w", err))
312310
return
313311
}
314-
c.opts.Logger.Debug(context.Background(), "sending offer", slog.F("offer", offer))
312+
c.logger().Debug(context.Background(), "sending offer", slog.F("offer", offer))
315313
select {
316314
case <-c.closed:
317315
return
318316
case c.localSessionDescriptionChannel <- offer:
319317
}
320-
c.opts.Logger.Debug(context.Background(), "sent offer")
318+
c.logger().Debug(context.Background(), "sent offer")
321319
}
322320

323321
var sessionDescription webrtc.SessionDescription
324-
c.opts.Logger.Debug(context.Background(), "awaiting remote description...")
322+
c.logger().Debug(context.Background(), "awaiting remote description...")
325323
select {
326324
case <-c.closed:
327325
return
328326
case sessionDescription = <-c.remoteSessionDescriptionChannel:
329327
}
330-
c.opts.Logger.Debug(context.Background(), "setting remote description")
328+
c.logger().Debug(context.Background(), "setting remote description")
331329

332330
err := c.rtc.SetRemoteDescription(sessionDescription)
333331
if err != nil {
@@ -350,13 +348,13 @@ func (c *Conn) negotiate() {
350348
_ = c.CloseWithError(xerrors.Errorf("set local description: %w", err))
351349
return
352350
}
353-
c.opts.Logger.Debug(context.Background(), "sending answer", slog.F("answer", answer))
351+
c.logger().Debug(context.Background(), "sending answer", slog.F("answer", answer))
354352
select {
355353
case <-c.closed:
356354
return
357355
case c.localSessionDescriptionChannel <- answer:
358356
}
359-
c.opts.Logger.Debug(context.Background(), "sent answer")
357+
c.logger().Debug(context.Background(), "sent answer")
360358
}
361359
}
362360

@@ -373,7 +371,7 @@ func (c *Conn) AddRemoteCandidate(i webrtc.ICECandidateInit) {
373371
if c.isClosed() {
374372
return
375373
}
376-
c.opts.Logger.Debug(context.Background(), "accepting candidate", slog.F("candidate", i.Candidate))
374+
c.logger().Debug(context.Background(), "accepting candidate", slog.F("candidate", i.Candidate))
377375
err := c.rtc.AddICECandidate(i)
378376
if err != nil {
379377
if c.rtc.ConnectionState() == webrtc.PeerConnectionStateClosed {
@@ -482,7 +480,7 @@ func (c *Conn) Dial(ctx context.Context, label string, opts *ChannelOptions) (*C
482480
}
483481

484482
func (c *Conn) dialChannel(ctx context.Context, label string, opts *ChannelOptions) (*Channel, error) {
485-
c.opts.Logger.Debug(ctx, "creating data channel", slog.F("label", label), slog.F("opts", opts))
483+
c.logger().Debug(ctx, "creating data channel", slog.F("label", label), slog.F("opts", opts))
486484
var id *uint16
487485
if opts.ID != 0 {
488486
id = &opts.ID
@@ -531,7 +529,7 @@ func (c *Conn) Ping() (time.Duration, error) {
531529
if err != nil {
532530
return 0, xerrors.Errorf("send ping: %w", err)
533531
}
534-
c.opts.Logger.Debug(context.Background(), "wrote ping",
532+
c.logger().Debug(context.Background(), "wrote ping",
535533
slog.F("connection_state", c.rtc.ConnectionState()))
536534

537535
pingDataReceived := make([]byte, pingDataLength)
@@ -568,12 +566,11 @@ func (c *Conn) isClosed() bool {
568566
func (c *Conn) CloseWithError(err error) error {
569567
c.closeMutex.Lock()
570568
defer c.closeMutex.Unlock()
571-
572569
if c.isClosed() {
573570
return c.closeError
574571
}
575572

576-
c.opts.Logger.Debug(context.Background(), "closing conn with error", slog.Error(err))
573+
c.logger().Debug(context.Background(), "closing conn with error", slog.Error(err))
577574
if err == nil {
578575
c.closeError = ErrClosed
579576
} else {
@@ -591,19 +588,21 @@ func (c *Conn) CloseWithError(err error) error {
591588
// Waiting for pion/webrtc to report closed state on both of these
592589
// ensures no goroutine leaks.
593590
if c.rtc.ConnectionState() != webrtc.PeerConnectionStateNew {
594-
c.opts.Logger.Debug(context.Background(), "waiting for rtc connection close...")
591+
c.logger().Debug(context.Background(), "waiting for rtc connection close...")
595592
<-c.closedRTC
596593
}
597594
if c.rtc.ICEConnectionState() != webrtc.ICEConnectionStateNew {
598-
c.opts.Logger.Debug(context.Background(), "waiting for ice connection close...")
595+
c.logger().Debug(context.Background(), "waiting for ice connection close...")
599596
<-c.closedICE
600597
}
601598

602599
// Waits for all DataChannels to exit before officially labeling as closed.
603600
// All logging, goroutines, and async functionality is cleaned up after this.
604601
c.dcClosedWaitGroup.Wait()
605602

606-
c.opts.Logger.Debug(context.Background(), "closed")
603+
c.logger().Debug(context.Background(), "closed")
604+
// Disable logging!
605+
c.loggerValue.Store(slog.Logger{})
607606
close(c.closed)
608607
return err
609608
}

0 commit comments

Comments
 (0)