<scribe> ScribeNick: dom
Jan-Ivar: a number of issues are
related to a unique problem that I want to introduce
... what if we could add/remove media without worrying about
state, glare, role or condition
... perfect handling includes handling glare with
rollback
... (only Firefox has rollback at the moment)
scribe: Perfect negotiation works
in Firefox but shows issues on our API
... [slide: Permise: Perfect negotiation]
... [slide: Premise: Perfect negotiation 2]
A simpler glare-proof setLocalDescription() #2165
A simpler non-racy rollback #2166
{iceRestart: true} works poorly with negotiationneeded #2167
Spec steps on stop() underestimate BUNDLE problem. #2176
transceiver.stop() needs more work (avoid BUNDLE footgun) #2150
jib: today, calling stop on the
offerer side works well
... now, when the answerer calls tc1.stop() there is a problem,
even in stable state
... JSEP and BUNDLE don't give affordance to stop only one of
the transceivers
... it stops all transceivers
... it also creates a racy behavior that breaks the
abstraction
... we can't fix JSEP and BUNDLE at this stage
... it's even worse than we thought since it affects the stable
state as well - you don't know in stable what comes next (SRD
vs SLD)
... the problem is that there is only one synchronous stopped
state
... the solution we came up with is a safer stop() method that
works only in createOffer, and a reject() method that only
works in have-local-offer
... JSEP doesn't foresee that approach
... Do we really need stop, though?
... addTrack and removeTrack were used together as participants
join/leave in Plan B
... but in Unified Plan, this accumulates resources -
transceiver are set as inactive, not ended
... the API is complicated due to having both tracks and
transceivers
... and transceivers need to be stopped explicitly - can't be
done automatically by the browser
... we had looked at a workaround using a dummy transceiver -
but that creates a separate footgun when using addTrack
Henrik: also has backwards compat issues
jib: also if done on both sides,
this would waste m-lines and create confusion
... so we want people to use stop(), but not having to think
about it
... Add
reject() + make stop() safe. New stopping state affects
createOffer only. #2220
Add reject() + make stop() safe. New stopping state affects createOffer only. #2220
jib: PR 2220 address this with a
new reject method, a new stopping attribute
... we trick JSEP in doing the right thing
... stopping still stops sending and receiving locally
... stop() for remote
... stopping is the synchronous local part
... and the rest is done asynchronously with negotiation
... this also sidesteps the whole bundle problem
... the reject() method sets both stopping (local) and stopped
(remote)
... reject() throw an error when not in have-remove-offer,
which is safer
henrik: there is such a thing as stopping before you are fully stopped - there may be discussion about how to expose it in the API, but the states exist
bernard: is stop() being used?
jib: it's not in Chrome, so few
people are using it
... we do need stop()
bernard: but do we need reject()?
henrik: I agree reject() may not be as needed
jib: the PR looks at splitting
the states - we can then talk about the reject() method is
needed
... [PR 2220: stopping solution to BUNDLE problem illustrated
(1/2)]
... when stopping is set, JSEP ignores it and negotiation
happens with tc1 not being stopping or stopped
... but its receiver track has ended through RTCP
signaling
... [PR 2220: stopping solution to BUNDLE problem illustrated
(2/2)]
... when tc1 is stopped, JSEP gets into play
... [PR 2220: stopping solution in simple case illustrated
(1/1)]
... still works in the simpler case (stop on offerer
side)
... [PR 2220: stop() sets new tc.stopping, affecting
createOffer only]
... [text from PR 2220]
... the important piece is that stopping-but-not-stopped
transceiver needs negotiation
henrik: does it matter if we don't reach stopped?
jib: we don't free resources
until we get to stopped
... most of the negotiation needed is orthogonal to the stopped
state
henrik: the transceiver object
still exists, but the expensive stuff (encoding, decoding) is
gone
... only the transport is left, but it is bundled anyway
jib: fair enough
... resources could already be cleaned up under the hood
indeed
... we mention specifically that stopping-but-not-stopped
transceiver doesn't affect createAnswer, to trick JSEP
... there is a note about the risks of using reject()
henrik: reject() doesn't remove the bundle footgun
jib: it's a bit safer since the
method throw an exception if in the wrong state
... it's only in rollback that you can get into trouble
henrik: the different between
stopping and rejecting is that when you're stopping, you're
waiting for an answer with an ack from the other side
... if you reject, you're sending the fact that you're stopping
but without ack
... this creates an additional risk of glare
... you get rid of a O/A exchange, but there is only limited
benefit beyond that
... and this makes the API more complex, with a footgun
... doesn't feel like an API I can imagine advise using
jib: my goal was to reduce the
number of ennemies - not removing functionality
... reject() reflects the current API feature
... I didn't want to assume nobody still needs that particular
feature
henrik: I'm fine with having this
discussion separately
... to me, the key thing is the distinction between stopping
and stopped
jib: these states are needed, at least as internal slots not matter what since it affects other algorithms
bernard: can we get consensus on
the stopping addition, and then on reject?
... any objection to the addition of stopping?
[silence]
RESOLUTION: consensus to add stopping state to the transceiver API
Bernard: what about reject()?
Henrik: I have an issue with it
Bernard: so do I
harald: removing it kind of
violates the assumption that any SDP state machine action can
be accomplished
... but it has always been a weak assumption
... I won't fight for it - would happy to not have it
Henrik: to me, SDP is a tool for our API - not everything that can be done in SDP needs to be exposed in the API, esp if it's a footgun
jib: Mozilla is also happy to
lose reject()
... would like to check with Cullen
Henrik: reject() is mostly an
optimization to skip a O/A
... also, does reject() interfere with rollback?
jib: no, neither stop nor reject
can be rolled back
... but there is a footgun if rejecting after a rollback
bernard: so I think we should merge stopping, and keep the reject() piece separate and seek whether there is consensus to bring it in
jib: I think I'm too in favor of removing it too
dom: what about implementation plans/
s_/_?
jib: Firefox will implement this - I have buy-in from the developer, and it shouldn't be hard to do, so soon
henrik: I want this to be implemented but can't commit for the short term
bernard: we do care about a bunch
of these things; I want to wait until we hear all the proposed
changes before making commitments
... we care about cleaning things about rollback
henrik: I feel perfect negotiation is a key part to completing WebRTC
{iceRestart: true} works poorly with negotiationneeded #2167
Add pc.restartIce() method. #2169
jib: the proposal is to add a
pc.restartIce() method that fires onnegotiationneeded
... it is implemented behind a pref in Firefox
... (only took a day or two implement in Firefox)
henrik: if you're already implementing ice restart, adding that method should indeed be quick
jib: most of the work was writing the tests indeed
henrik: I think we should do this - it is simple and avoid problems
bernard: any object to adopting 2169?
RESOLUTION: consensus to add restartIce method per PR 2169
A simpler glare-proof setLocalDescription() #2165
A simpler non-racy rollback #2166
{iceRestart: true} works poorly with negotiationneeded #2167
jib: the problem here is how to
deal with rollback when avoiding glare
... the issue is what happens when an ice candidate arrives at
the wrong time; we have an operations queue that helps here,
but this requires Promise.all to queue operations in the right
order, which isn't intuitive and is unlikely to happen
... the proposed approach is to use an option to SRD for
rollback instead of considering as a separate type
henrik: only Firefox has implemented rollback; if one is to start from scratch, any reason to implement rollback in SLD?
jib: deprecating that would make
sense to me
... but that's removing a feature again
... although rollback is at risk in any case
... an alternative would be to always do the rollback dance
implicitly (assuming rollback true always)
harald: it would change the behavior of SRD by making it accept descriptions it would have rejected before
jib: right
henrik: the breaking change is
implicit rollback hides a possible mistake
... that doesn't sound bad to me - implicit would work for me,
although I could go with explicit as well
jib: the issue with implicit is that rollback is not necessarily obvious to manage, leading the JS to a weird state
bernard: any preference on proposal A (explicit) vs B (implicit)?
harald: slight preference for implicit, but won't die on that hill
bernard: anyone prefers A over B?
[silence]
bernard: sounds like a marginal preference for B
jib: the only downside is that
it's less explicit
... in any case, I'm not hearing push back against doing
something to that effect (A or B)
henrik: the advantage of B is that it simplifies the usage of the API - makes it harder to mis-use it
bernard: but it makes rollback an essential feature of SRD
henrik: indeed, it makes not
supporting rollback create interop issues
... so rollback is implemented, B sounds better
dom: what about implementation plans for rollback?
bernard: microsoft is ready to allocate resources to implement this - not sure how long it will take, it's complex
jib: wpt tests are pretty thorough on rollbacks
henrik: great to hear resources coming from microsoft on this
bernard: it will be a priority, but not sure about schedule
henrik: will be happy to code-review
jib: pranswer is not implemented
in Firefox, so not sure about interferences with rollback
... may be useful to consider keeping rollback and pranswer
uncoupled
bernard: I think this will
increase the chance of getting rollback done
... rollback is already marked at risk - this increases the
motivation of doing it
... so how about going with proposal B?
RESOLUTION: we add implict rollback to SRD per Proposal B (with updated PR2212)
harald: this can be feature-detected too
jib: onnegotiationneeded appears
to be racy and glare-prone from our earlier "polite peer"
exercise
... again, the current API can be made to avoid this issue, but
is unlikely to be used correctly
... two proposals: implict call createOffer/createAnswer if no
sdp given to SLD
... or automatically set the right type based on signaling
state
... the SDP argument passed to SLD is in fact unused
today
... both proposals are 100% backwards compatible, and SRD
wouldn't be affected
henrik: I like this
... now that SDP munging prohibited, the split between
createO/A and SL/RD is artificial, and making them race-free
sounds good
... between A or B, I prefer type to be explicit - otherwise
makes it harder to debug, so prefer A
bernard: anyone prefers B over A?
jib: I prefer B over A because
it's a nicer API
... we can infer from the state what is being asked
harald: you have to do a state switch in any case to send it conditionally
henrik: also could lead to errors in assumptions of current state
jib: the assumption is already that the JS has to know the state it is in before calling this
bernard: it's not that you never have to provide a type - you can skip providing it (in proposal B)
henrik: so in B, if you do provide a type, you can still get an error?
jib: yes
henrik: then I'm fine with that
RESOLUTION: adopt proposal B in glare-proof SLD
Negotiation methods are vestigial, racy with a pushy SFU. #2221
jib: a problem spotted by fippo
with "push" SFUs that keep pushying offers
... the strategy to deal with this still needs to use
Promise.all
... there is a proposal here to fix this with a combined
setRemoveAndLocalDescriptions
harald: there is another
strategy: you process incoming messages as they come in
... that's why we allow SRD in have-remove-offer state
... if you want to do FIFO, you use Promise.all
... if you want to do LIFO, you don't need it
jib: you could also
rollback
... what I wanted to solve is avoiding signaling states
collision
... this shows that our negotiation methods were built for
another time
henrik: yes, a lot of these 4
steps should really just be 2 steps
... in that sense, combining them is good idea - would also be
easy to implement
... one argument against this is about pushy SFUs
... if we implement perfect negotiation, I don't think we would
have a pushy peer
bernard: the case I typicall see,
the conference unit is the one making the offer
... when people keep coming in, it needs to keep sending
offers
... so that situation happens a lot
henrik: my point was that if
perfect negotiation is framed in terms of p2p, and that an SFU
does something out of this context, then it's the
responsibility of the SFU to take care of Promise.all
... but I can see the value of dealing easily with pushy
SFUs
harald: it feels like an
optimization that forces a specific type of negotiation
... it feels wrong to munge so much into one thing
henrik: feels not very high value
(but also not very hard to implement)
... the other things presented earlier felt more important
harald: with a pushy SFU, you need to pick a FIFO or LIFO strategy - I don't think the API should force one approach or not
jib: the main issue is that it's
easy to do it wrong
... although it gets exposed as invalidstateerror, so it can be
detected
henrik: my main point is that the SFU use case targets a different type of developers than a typical P2P connection
jib: a peer could act as a pushy peer with rollback
henrik: can a pushy peer exist with perfect negotiation?
bernard: I don't think so
henrik: if perfect negotiation
has that problem, I would agree with adding the API to avoid
races
... but if not in the context of perfect negotiation, feels
like a nice to have, not essential
bernard: right - it's an edge case
dom: if only nice to have, would prefer not to have it in 1.0
harald: would also prefer not having this in
RESOLUTION: no consensus to add setRemoteAndLocalDescriptions
henrik: we agreed that
tc.stopping is a good idea and not have reject()
... you rarely care about stopping vs stopped
... the only reason we deal with this is to avoid the BUNDLE
footgun
... do we really need this amount of granularity?
... can this be exposed with fewer API changes?
... my proposal is to treat stopping as a "stopped"
direction
... then the difference is between stopped and stopping is then
visible by looking at direction vs currentDirection
... we can even remove the stop() method if so (could set the
attribute instead)
... the only limitation is that you can no longer checker the
direction when stopping
... but once you're stopping, the direction doesn't really
matter at that point
... it makes the API a bit cleaner and hides the complexity
some more
jib: I don't think I like this -
3 problems with it
... direction has matched JSEP / SDP for a long time, and this
breaks this
... worry about the edge case about when you're locally stopped
and the other side doesn't know yet, directions may change
henrik: I'm not suggestion we
change the [[Direction]] internal slot, but the attribute only
would reflect a different value
... once it's stopping, it's not sending or receiving - the
direction no longer matters
jib: I'm not sure I understand when that is set - when stopping or stopped?
henrik: t.direction= "stopped" is stopping, t.currentDirection = "stopped" is stopped
jib: think I like the old API better
harald: I like the stop() method - it's more explicit
henrik: fine with the stop() method, but would use direction to keep track of the state
jib: but JSEP defines stopped, we can't remove it
harald: I like the proposal (having seen it an hour ago)
bernard: can't record a consensus at the moment
This is scribe.perl Revision: 1.154 of Date: 2018/09/25 16:35:56 Check for newer version at http://dev.w3.org/cvsweb/~checkout~/2002/scribe/ Guessing input format: Irssi_ISO8601_Log_Text_Format (score 1.00) Succeeded: s/stop()/stopping/ Succeeded: s/reject()/stop()/ Succeeded: s/push/pushy/ Present: Bernard Jan-Ivar Harald Henrik Lennart_Schulte Marten Pallab_Gain Patrick_Rockhill Karthik Dom Lennart_Grahl Carine Alexandre_Gouaillard Found ScribeNick: dom Inferring Scribes: dom Agenda: https://www.w3.org/2011/04/webrtc/wiki/July_2_2019 WARNING: No date found! Assuming today. (Hint: Specify the W3C IRC log URL, and the date will be determined from that.) Or specify the date like this: <dbooth> Date: 12 Sep 2002 People with action items: WARNING: IRC log location not specified! (You can ignore this warning if you do not want the generated minutes to contain a link to the original IRC log.)[End of scribe.perl diagnostic output]