Re: Proposal: Remove stopped transceivers to prevent resource exhaustion

> On Feb 15, 2019, at 3:02 AM, Henrik Boström <hbos@google.com> wrote:
> 
> Howdy WebRTC enthusiasts.
> 
> Issue: Remove stopped transceivers from getTransceivers() <https://github.com/w3c/webrtc-pc/issues/2092>
> 
> TL;DR: Keeping transceivers around prevents garbage collection of a possibly ever-growing list of tracks. Can we stop doing that?
> 
> If an application does addTrack() and removeTrack() with renegotiations in-between, the list of m= sections and transceivers will grow over time. RTCRtpTransceiver.stop() allows negotiating that an m= section is no longer used, and in subsequent renegotiations that m= section could be recycled for future transceivers preventing the SDP from growing indefinitely. However, currently the set of transceivers <https://w3c.github.io/webrtc-pc/#transceivers-set> (getTransceivers()) is never cleaned up and will grow indefinitely.
> 
> This prevents the transceivers, and thus the associated senders/receivers and tracks, from being garbage collected. A stress test running Chrome that did add/removeTrack a lot ran out of memory when we switched from Plan B to Unified Plan due to this resulting in a few thousand transceivers in less than a minute. (I don't know the true footprint, but even if each transceiver just has a single video frame in its buffer of 1280x720x4, that's several megabytes, multiplied by thousands of transceivers => gigabytes of data).

I agree with the concern.
That said, implementations could probably do some clean-up when a transceiver is stopped so that it becomes very lightweight.
Is there anything preventing implementations to do so?

> 
> Shall we make stopping a transceiver remove it from the connection's set of transceivers?

I support this.
RTCPeerConnection objects are difficult to GC, making them slimmer seems good to me.
It does not seem like we loose much functionality here.

> 
> Note: It is still possible to prevent the list of transceivers from growing by manually recycling them using transceiver.sender.replaceTrack() and transceiver.direction, but that still wastes resources on transceivers currently not used, and implies you probably shouldn't use transceiver.stop() in most cases.
> 
> Related issues/questions:
> If you care about mids of stopped transceivers you'd have to record them yourself.
> There is no "onstopped" event in case a transceiver is stopped due to setRemoteDescription(). Should we add one, or is it enough that the application checks whether the transceiver still exists by querying getTransceivers() in track.onmute?
Current events seem ok for received tracks.
It sounds a bit weird to check for the receiver track onended event in the case of a sendonly transceiver getting stopped by the other side.
One use-case is that a web application wants to do some clean-up like stopping the track being sent.
An ‘onstopped’ event might be handy but does not seem necessary since there are ways to do this in JS.

Received on Friday, 15 February 2019 17:18:15 UTC