Open
Bug 1169386
Opened 9 years ago
Updated 2 years ago
Avoid queuing a task ahead of peerConnection operations in the non-corner case.
Categories
(Core :: WebRTC, defect, P4)
Tracking
()
NEW
backlog | webrtc/webaudio+ |
People
(Reporter: jib, Assigned: jib)
References
()
Details
(Whiteboard: [spec compliance])
Attachments
(2 files)
For spec-compliance, we should not queue a task before executing createOffer/setLocalDescription/setRemoteDescription/AddIceCandidate when there are no pending operations. Spec behavior is: Running sync on empty is the common case, whereas chaining is a corner-case. This means that we want: pc.addTrack(X); pc.createOffer(); pc.addTrack(Y); where Y is never part of the offer. The exception is in: pc.setRemoteDescription(desc); // not checking for failure! pc.addTrack(X); pc.createOffer(); pc.addTrack(Y); where Y IS part of the offer, by nature of the createOffer being deferred. This is considered a natural outcome of a deprecated pattern. Use promises. This regressed in 37 (Bug 1106675) when we started always chaining operations (Y is always part of the offer), a well-intended move, but nevertheless non-compliant.
Assignee | ||
Comment 1•9 years ago
|
||
Try - https://treeherder.mozilla.org/#/jobs?repo=try&revision=bed72b9d0f5e
Assignee | ||
Comment 2•9 years ago
|
||
Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case.
Attachment #8612474 -
Flags: review?(martin.thomson)
Assignee | ||
Comment 3•9 years ago
|
||
Comment on attachment 8612474 [details] MozReview Request: Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case. Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case.
Assignee | ||
Comment 4•9 years ago
|
||
Realizing from trip-up above that we don't have a test for this. Will add one shortly.
Comment 5•9 years ago
|
||
https://reviewboard.mozilla.org/r/9583/#review8365 I think that we probably want to test this somehow. Maybe add a clause to dom/media/tests/mochitest/test_peerConnection_syncSetDescription.html ::: dom/media/PeerConnection.js:443 (Diff revision 2) > + this._operations = p.then(() => this._operationsLength--, > + () => this._operationsLength--); Why not `.catch(_ => {}).then(_ => --this._operationsLength)` ::: dom/media/PeerConnection.js:430 (Diff revision 2) > - let p = this._operationsChain.then(() => { > + let p = (!this._operationsLength)? func() : this._operations.then(() => { Are we *certain* that func() returns a promise? It might make sense to wrap it: Promise.resolve(func()) Also, don't use the ?: operator here. An if statement will do.
Comment 6•9 years ago
|
||
And I see that you have already volunteered to create a test. We must be doing something right (and I need to review the bug before reviewing the patch...)
Assignee | ||
Comment 7•9 years ago
|
||
(In reply to Martin Thomson [:mt] from comment #5) > ::: dom/media/PeerConnection.js:443 > (Diff revision 2) > > + // Note: Decrement must run before other p.then's, so don't extend fork! > > + this._operations = p.then(() => this._operationsLength--, > > + () => this._operationsLength--); > > Why not `.catch(_ => {}).then(_ => --this._operationsLength)` Because that would extend the fork and run afoul of the comment above it ^ > ::: dom/media/PeerConnection.js:430 > (Diff revision 2) > > - let p = this._operationsChain.then(() => { > > + let p = (!this._operationsLength)? func() : this._operations.then(() => { > > Are we *certain* that func() returns a promise? It might make sense to wrap > it: > Promise.resolve(func()) I'm certain. That would mean chaining a synchronous method or an async method that forgot to return its promise (a timing nightmare), so I think I would rather have a JS error in that case. > Also, don't use the ?: operator here. An if statement will do. That was my favorite part.
Comment 8•9 years ago
|
||
(In reply to Jan-Ivar Bruaroey [:jib] from comment #7) > (In reply to Martin Thomson [:mt] from comment #5) > > ::: dom/media/PeerConnection.js:443 > > (Diff revision 2) > > > + // Note: Decrement must run before other p.then's, so don't extend fork! > > > + this._operations = p.then(() => this._operationsLength--, > > > + () => this._operationsLength--); > > > > Why not `.catch(_ => {}).then(_ => --this._operationsLength)` > > Because that would extend the fork and run afoul of the comment above it ^ OK, I really don't having to rely on races. That's what cause the last mess. Can you put the counter decrement in differently? if (this._operationsLength > 0) { p = func(); } else { p = this._operationsChain.then(() => func()); // add the closed check, I'm lazy. } ++this._operationsLength; p = p.then(r => { --this._operationsLength; return r; }, e => { --this._operationsLength; throw e; }); this._operationsChain = p.catch(() => {});
Assignee | ||
Comment 9•9 years ago
|
||
(In reply to Martin Thomson [:mt:] from comment #8) > (In reply to Jan-Ivar Bruaroey [:jib] from comment #7) > > (In reply to Martin Thomson [:mt] from comment #5) > > > ::: dom/media/PeerConnection.js:443 > > > (Diff revision 2) > > > > + // Note: Decrement must run before other p.then's, so don't extend fork! > > > > + this._operations = p.then(() => this._operationsLength--, > > > > + () => this._operationsLength--); > > > > > > Why not `.catch(_ => {}).then(_ => --this._operationsLength)` > > > > Because that would extend the fork and run afoul of the comment above it ^ > > OK, I really don't having to rely on races. That's what cause the last > mess. This is actually not a "race" but well-defined. Multiple p.then()s is guaranteed FIFO. > Can you put the counter decrement in differently? > > if (this._operationsLength > 0) { > p = func(); > } else { > p = this._operationsChain.then(() => func()); // add the closed check, I'm > lazy. > } > ++this._operationsLength; > p = p.then(r => { > --this._operationsLength; > return r; > }, e => { > --this._operationsLength; > throw e; > }); > this._operationsChain = p.catch(() => {}); I considered this, but it adds an extra dispatch always for no reason, upsetting the timing of the passed-in function, a worse maintenance headache imho.
Assignee | ||
Comment 10•9 years ago
|
||
I mean multiple .then()s on the same promise.
Comment 11•9 years ago
|
||
(In reply to Jan-Ivar Bruaroey [:jib] from comment #9) > I considered this, but it adds an extra dispatch always for no reason, > upsetting the timing of the passed-in function, a worse maintenance headache > imho. I could care less about the extra dispatch, but I'm interested in what you think might be affected by this. If func() is setLocalDescription(), how is this extra dispatch any different from that function just taking one extra cycle to do its work? Ultimately, this is just wallpapering over the real problem, which is that the operations queue is fundamentally broken. How about we fix that in the spec instead (and until then, this will have to suffice).
Comment 12•9 years ago
|
||
Why do you think the operations queue is broken?
Comment 13•9 years ago
|
||
It's "special" and that means we have long discussions like this. Other APIs don't try to add all affordances for programmers that don't know how to use them properly, they throw if methods are invoked from the wrong state. We should too.
Comment 14•9 years ago
|
||
I don't think that the issue is that that things are being invoked in the wrong state, but rather that without the queue you are requiring things to be done in lockstep which is a pain.
Assignee | ||
Comment 15•9 years ago
|
||
(In reply to Martin Thomson [:mt:] from comment #11) > (In reply to Jan-Ivar Bruaroey [:jib] from comment #9) > > I considered this, but it adds an extra dispatch always for no reason, > > upsetting the timing of the passed-in function, a worse maintenance headache > > imho. > > I could care less about the extra dispatch, but I'm interested in what you > think might be affected by this. If func() is setLocalDescription(), how is > this extra dispatch any different from that function just taking one extra > cycle to do its work? We never landed the patch in Bug 1157042, so this would likely do actual damage to the time-sensitive setLocalDescription (which is implemented across c++ and JS) by delaying the SetLD success callback until after the first onicecandidate fires from c++ (through PeerConnection.js to the user).
Updated•9 years ago
|
backlog: --- → webRTC+
Rank: 30
Priority: -- → P3
Whiteboard: [spec compliance]
Assignee | ||
Comment 16•9 years ago
|
||
Comment on attachment 8612474 [details] MozReview Request: Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case. Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case.
Attachment #8612474 -
Flags: review?(martin.thomson)
Assignee | ||
Comment 17•9 years ago
|
||
Bug 1169386 - test addTrack(X); createOffer(); addTrack(Y);
Attachment #8615468 -
Flags: review?(martin.thomson)
Assignee | ||
Updated•9 years ago
|
Attachment #8612474 -
Flags: review?(martin.thomson)
Assignee | ||
Comment 18•9 years ago
|
||
Comment on attachment 8612474 [details] MozReview Request: Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case. Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case.
Assignee | ||
Comment 19•9 years ago
|
||
Comment on attachment 8615468 [details] MozReview Request: Bug 1169386 - test addTrack(X); createOffer(); addTrack(Y); Bug 1169386 - test addTrack(X); createOffer(); addTrack(Y);
Assignee | ||
Comment 20•9 years ago
|
||
Note that the tests will fail because of Bug 1171634.
Comment 21•9 years ago
|
||
https://reviewboard.mozilla.org/r/9583/#review9227 Our increasingly brittle timing still bothers me a great deal. ::: dom/media/tests/mochitest/test_peerConnection_operations.html:26 (Diff revision 4) > + .reduce((a,l) => (l.startsWith("m=") && a.push(l), a), []) This is unnecessarily cryptic. I find your aversion to braces a little too aggressive. is(offer.sdp.split('\nm='), 2)
Comment 22•9 years ago
|
||
Comment on attachment 8615468 [details] MozReview Request: Bug 1169386 - test addTrack(X); createOffer(); addTrack(Y); Gah, you get used to reviewing the whole block, and now you have to individually r+ each piece.
Attachment #8615468 -
Flags: review?(martin.thomson) → review+
Comment 23•9 years ago
|
||
Comment on attachment 8612474 [details] MozReview Request: Bug 1169386 - avoid queueing a task ahead of pc operations in the non-corner case. I still don't like the brittle timing here.
Attachment #8612474 -
Flags: review?(martin.thomson) → review+
Comment 24•7 years ago
|
||
Mass change P3->P4 to align with new Mozilla triage process.
Priority: P3 → P4
Updated•2 years ago
|
Severity: minor → S4
You need to log in
before you can comment on or make changes to this bug.
Description
•