- From: Harald Alvestrand <harald@alvestrand.no>
- Date: Mon, 04 May 2015 20:31:10 +0200
- To: Jan-Ivar Bruaroey <jib@mozilla.com>, Stefan Håkansson LK <stefan.lk.hakansson@ericsson.com>, "public-webrtc@w3.org" <public-webrtc@w3.org>
- Message-ID: <5547BAEE.7080108@alvestrand.no>
On 05/04/2015 07:47 PM, Jan-Ivar Bruaroey wrote: > On 5/4/15 11:47 AM, Harald Alvestrand wrote: >> Because it leads to exactly the behavior you outlined in your >> analysis: The user does a set of operations in a certain sequence; >> the result of the operation has some of the operations the user >> thinks of as "earlier" being affected by some of the operations the >> user thinks of as "later". > > User perception was not part of my analysis. I focused on two > inherently non-deterministic properties of the createOffer() function > (and its siblings): > > 1. Its observable behavior varies depending on whether something is > on the internal queue or not (action at a distance). > > 2. Iff nothing is on the queue (or in absence of a queue FWIW), then > a parallel thread will be running when the call returns, making it > impossible to reason about the effects of even subsequent > synchronous JS actions on things already underway. > Does the JS programming model allow truly parallel threads? I have been told many times that the JS event loop requires that things must happen as if only one piece of JS is active at any one time, and that therefore most of the locks and critical section mechanisms we're used to in other languages are not needed in JS. (I've always taken this to mean that any effect of true parallelism has to be hidden from JS, rather than imagining that it's truly single-threaded.....) If this is still true, we're talking about actions being taken in the next task to be taken off the main event queue, so we can still reason about what happens between "now" and the end of this function. > 1. > > > > > If we were to queue always (my PR) then both problems (carefully > narrowed in scope to sync JS actions only!) would go away. > >> Furthermore, as soon as the sequence of operations gets broken up by >> visits to the event loop, it goes back to being nondeterministic: >> >> addTrack(X); createOffer(); addTrack(Y) is deterministic (but >> surprising). > > This is the sync case, and it is *not* deterministic yet without my PR. > > Now on to the trickier concern I believe you and Stefan are raising > (which is outside the scope of my PR)... > >> addTrack(X); createOffer(); >> irrelevant-promise-returning-operation().then(s => addTrack(Y)) is >> non-deterministic. (apologies if I miswrote the => syntax). > > (Syntax LGTM!) Right, a tough question: Are asynchronous operation > outcomes (to be) insulated from timed JS events? > > The practical question may be: Can the JS app, right before calling > addTrack(Y), determine the effect it will have? In an earlier answer, > I found the on-queue case to be detectable, it's once the operation > runs (its parallel thread) that things become non-deterministic. > > How to close this window? Perhaps we could make the senders arguments > to the internal operation's function? E.g. > > createOffer: function() { > return this._chain(() => internalCreateOffer(this.getSenders())); > } > > That might work, and not bother anyone. That might work - being explicit that createOffer is being done based on the senders that exist at the point in the code where createOffer is called. In writing the text, this will mean that createOffer gets a description that says "first marshall the stuff you're going to take action on, then queue a task to actually do your action". There's many pieces of such description in HTML5 and elsewhere, I believe, so we should not be lacking in models. Just hope we can avoid inventing any new terms of art while describing this :-)
Received on Monday, 4 May 2015 18:31:41 UTC