[webrtc-pc] statechange fired synchronously before state on RTCSctpTransport; no event on closed (#2622)

jan-ivar has just created a new issue for https://github.com/w3c/webrtc-pc:

== statechange fired synchronously before state on RTCSctpTransport; no event on closed ==
_"Once an [SCTP transport is connected](https://w3c.github.io/webrtc-pc/#dfn-rtcsctptransport-connected)"_ we fail to queue a task when we _"... [Fire an event](https://dom.spec.whatwg.org/#concept-event-fire) named [`statechange`](https://w3c.github.io/webrtc-pc/#event-sctptransport-statechange) at transport."_

This violates years of precedence to not alter observable state while JS is running:
```js
pc.sctp.addEventListener("statechange", A);
for (let i = 0; i < N; i++) ; // busy-loop
pc.sctp.addEventListener("statechange", B); // A and B should receive same # of events for all values of N 
```
An oversight, as it seems uncontroversial this algorithm was meant to be in a queued task like all the others.

But the algorithm also fails to set [[[SctpTransportState]]](https://w3c.github.io/webrtc-pc/#dfn-sctptransportstate) before firing, breaking obvious behavior:
```js
pc.sctp.onstatechange = () => console.log(pc.sctp.state); // should be new state, not previous state!
```

When I click on [[[SctpTransportState]]](https://w3c.github.io/webrtc-pc/#dfn-sctptransportstate) in the spec, it shows only two references: the `state` [getter](https://w3c.github.io/webrtc-pc/#dom-rtcsctptransport-state) and the [pc close algorithm](https://w3c.github.io/webrtc-pc/#dfn-close-the-connection), which at first made me think we never update any state but `"closed"`.

But prose to queue a task to update state is hiding in the [enum descriptions](https://w3c.github.io/webrtc-pc/#dom-rtcsctptransportstate), E.g. _"When the negotiation of an association is completed, a task is queued to update the [[[SctpTransportState]]](https://w3c.github.io/webrtc-pc/#dfn-sctptransportstate) slot to "[connected](https://w3c.github.io/webrtc-pc/#idl-def-RTCSctpTransportState.connected)". "_ Which is good I suppose, as it ensures:
```js
const A = pc.sctp.state;
for (let i = 0; i < N; i++) ; // busy-loop
const B = pc.sctp.state; // A and B should be identical for all values of N
```
But this is after the `statechange` event has fired in the `"connected"` case, and fires no event at all in the `"closed"` case, which seems wrong since there are cases like remote close that isn't covered by the [pc close algorithm](https://w3c.github.io/webrtc-pc/#dfn-close-the-connection).

PS: This may be causing [a Firefox bug found on StackOverflow](https://stackoverflow.com/questions/66067571/are-rtcdatachannels-guaranteed-to-open-after-the-ice-state-becomes-connected), and fixing it should help cement the already [noted](https://w3c.github.io/webrtc-pc/#h-note-57) intent to have data channel `open`fire after all this.

Please view or discuss this issue at https://github.com/w3c/webrtc-pc/issues/2622 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Saturday, 6 February 2021 15:36:28 UTC