TEL-886: Media Port rework - #802
Conversation
11f4b21 to
dd06f29
Compare
|
Huh, the race in CI is real, and is apparently a problem in media-sdk (yay zerocopy) that previous tests simply did not expose. |
Will fix this in media-sdk. |
6a063e6 to
dce2728
Compare
| negotiated *sdp.MediaConfig | ||
|
|
||
| audioIn *msdk.WriteCloserSwitch[msdk.PCM16Sample] // SIP RTP -> LK PCM | ||
| audioOut *msdk.WriteCloserSwitch[msdk.PCM16Sample] // LK PCM -> SIP RTP |
There was a problem hiding this comment.
Why these two are pointers, but the other two are not?
There was a problem hiding this comment.
ha, nice catch.
We want to initialize the audio ones with msdk.NewWriteCloserSwitch, so that's why they're pointers.
Why the other ones are not? No reason. Fixed.
There was a problem hiding this comment.
Aren't they safe to use as zero values?
| return errors.New("unexpected local address change") | ||
| } | ||
|
|
||
| audioToPort := p.audioOut.Swap(nil) // either nil or no-op closer |
There was a problem hiding this comment.
Maybe assert that it's the case during swap?
There was a problem hiding this comment.
Not sure I follow. Are you talking about something like:
audioToPort := p.audioOut.Swap(nil)
if audioToPort != nil {
if _, ok := audioToPort.(msdk.writeCloser[x]); !ok {
log.Errorw(...)
}
}
?
The only thin that swaps these is the configure function itself, so I'm not sure what the benefit would be there.
The comment is there to explain why we don't close the popped value.
|
|
||
| // WriteOutboundDTMFTo tells the room where to send DTMF to. | ||
| // Returns the previously-set writer (if one exists). | ||
| WriteOutboundDTMFTo(w msdk.WriteCloser[*livekit.SipDTMF]) msdk.WriteCloser[*livekit.SipDTMF] |
There was a problem hiding this comment.
Any specific reason to use pointers in livekit.SipDTMF? It's a tiny payload, might as well just copy it around.
There was a problem hiding this comment.
I guess the thread safety is a good benefit of copying. Fair enough.
There was a problem hiding this comment.
WriteSample passes lock by value: github.com/livekit/protocol/livekit.SipDTMF contains google.golang.org/protobuf/runtime/protoimpl.MessageState contains sync.Mutex I guess this is one,
There was a problem hiding this comment.
Oh, right, it's a protobuf. Can we swap it for a non-proto struct? I remember we had races on proto structs before.
47b61bd to
5ad9b22
Compare
Fixed in media-sdk#81. |
4c60a45 to
470911b
Compare
|
|
||
| // WriteOutboundDTMFTo tells the room where to send DTMF to. | ||
| // Returns the previously-set writer (if one exists). | ||
| WriteOutboundDTMFTo(w msdk.WriteCloser[*livekit.SipDTMF]) msdk.WriteCloser[*livekit.SipDTMF] |
There was a problem hiding this comment.
Oh, right, it's a protobuf. Can we swap it for a non-proto struct? I remember we had races on proto structs before.
| negotiated *sdp.MediaConfig | ||
|
|
||
| audioIn *msdk.WriteCloserSwitch[msdk.PCM16Sample] // SIP RTP -> LK PCM | ||
| audioOut *msdk.WriteCloserSwitch[msdk.PCM16Sample] // LK PCM -> SIP RTP |
There was a problem hiding this comment.
Aren't they safe to use as zero values?
| if s.cli != nil { // Process reinvite for existing outbound calls | ||
| oc := s.cli.getActiveCall(cc.ID()) | ||
| newCSeq := cc.InviteCSeq() | ||
| if oc != nil && oc.cc != nil && oc.cc.InviteCSeq() < newCSeq { |
There was a problem hiding this comment.
This is pre-existing, behavior, but, in a follow-up PR, we should reply with some kind of error if the new sequence number is lower than the existing one (per spec, I think this should be internal server error). Adding a todo.
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
| if old := c.lkRoom.WriteOutboundAudioTo(nil); old != nil { | ||
| old.Close() | ||
| } |
There was a problem hiding this comment.
🟡 Dial-tone transfer closes the reused outbound audio writer
When a transfer plays dial-tone, WriteOutboundAudioTo(nil) returns the media port's own outbound writer and old.Close() closes it. That same writer (GetOutboundAudioWriter) is then used to play ringback and is re-attached to the room if the transfer fails, so ringback can be silent and a failed transfer can leave the caller with no room audio.
| if old := c.lkRoom.WriteOutboundAudioTo(nil); old != nil { | |
| old.Close() | |
| } | |
| c.lkRoom.WriteOutboundAudioTo(nil) |
Was this helpful? React with 👍 or 👎 to provide feedback.
This change is intended to: