W3C home > Mailing lists > Public > public-webrtc@w3.org > December 2017

[webrtc-pc] When to fire events triggered by setRemoteDescription.

From: henbos via GitHub <sysbot+gh@w3.org>
Date: Fri, 08 Dec 2017 09:30:10 +0000
To: public-webrtc@w3.org
Message-ID: <issues.opened-280426487-1512725408-sysbot+gh@w3.org>
henbos has just created a new issue for https://github.com/w3c/webrtc-pc:

== When to fire events triggered by setRemoteDescription. ==
In the spec, we have explored two approaches to firing events as a result of processing the result of an SRD call:
1. Schedule to fire an event.
2. Fire the event immediately midst-processing.

Both are problematic. 1) is problematic because when we fire later, the states of the event might no longer represent the state that caused the event to fire, and 2) is problematic because the event handler could influence the SRD algorithm.

This issue proposes handling all events triggered by SRD - including pc.ontrack, stream.onaddtrack/onremovetrack, track.onmute/onunmute - the way we handle ontrack. That is: the SRD algorithm creates and adds each event to a list, then when the algorithm is done but before the promise is resolved, we do "for each event, fire event".

For more details, here's essentially what I wrote on https://github.com/w3c/webrtc-pc/pull/1667#discussion_r155505342:

Generally speaking, events are typically scheduled to fire later, so by the time they do the effects of multiple events have already occurred. I think this is bad because the event handler gets fired with objects whose state are not even guaranteed to represent the state that caused them to fire.

Firing the events before the last step is not only important because we want the events to fire before the promise resolves, but because if we don't then calling SRD twice or doing other things before the events fire will yield track information in the event handlers that don't correlate with the event that caused them to fire.

I also argue that we cannot fire events midst-processing, or else the event handler can both inspect and influence the state of processing algorithm. Something as simple as "for each transceiver, fire an event on the transceiver" would be problematic because the event handler could modify the set of transceiver (or any other state of the PC that the processing algorithm might use) while we are iterating them.

What if you close the pc or stop or add a track in one of the event handlers? The SRD algorithm would have to handle substeps of the algorithm failing. Even if we know we are safe for now, this is not resilient to future changes and implementations are error prone if they don't think about this stuff, like copying or making sure any container is iterable even if it's modified during iteration or else we might crash.

I argue we must:
1. Fire all events after any processing steps.
2. Have fired all events before the last step (before promise is resolved).

So, if a stream with two tracks are both removed, stream.onremovetrack fires twice and in both events stream.getTracks().length == 0, even on the first track's removal event.
The guarantee is: the state of any object in an event is up-to-date with the result of the SRD call. Meaning the stream is empty.

This is consistent with ontrack. If you add two tracks to a stream, inspecting the stream in the first ontrack yields it contains two tracks. If this wasn't the case you would also have a confusing problem:
// Imagine streams only contain the tracks whoose ontrack has fired.
pc.ontrack = (e) => {
  // Shared streams are processed multiple times for each ontrack,
  // we don't know which event represents the final state of the
  // stream, and this is sensitive to the machinery. It's better
  // that each object in any event fired represent the end-result
  // of the SRD.
Guaranteeing the state of the objects represent the end of the SRD is easy to understand, consistent with other event mechanisms and safer and easier to implement.

People should write code handling the end-result, not half-way results. They shouldn't have to care about whether adding or removing tracks from streams is implemented as a an iteration of smaller operations or as an all-or-nothing operation.

Please view or discuss this issue at https://github.com/w3c/webrtc-pc/issues/1691 using your GitHub account
Received on Friday, 8 December 2017 09:30:14 UTC

This archive was generated by hypermail 2.3.1 : Friday, 8 December 2017 09:30:14 UTC