3 ms·
Does your concurrent runtime guarantee that scripts will be executed as if they were running on a single-threaded runtime ? Consider a naive function that quer
by victorNicollet 11y ago
Does your concurrent runtime guarantee that scripts will be executed as if they were running on a single-threaded runtime ?
Consider a naive function that queries several asynchronous data sources and constructs an array of all distinct responses:
function distinct(sources, next) {
var left = sources.length;
var result = [];
for (var i = 0; i < sources.length; ++i)
sources[i].query(process);
function process(data){
if (result.indexOf(data) < 0) result.push(data);
if (--left == 0) next(result);
}
}
This code can only work if each call to `process()` is executed atomically, start-to-finish, without another call touching `result` or `left`. In any language but JS, this would be an obvious race condition. But JS guarantees that there will be no concurrent access, and plenty of third-party code relies (perhaps unknowingly) on this serial execution property.
Yes, this could have been implemented as a join, followed by duplicate elimination from the array of results, but it wasn't, and you'll find plenty of JS code which reinvents the wheel in a similar way. Even worse: you can't be sure that a given JS plugin or dependency _doesn't_ rely on single-threaded evaluation without an in-depth code review.
I'm not saying that your concurrent runtime is a bad idea. In fact, I think it's an absolutely great idea, but I also know that it's an insanely _hard_ thing to implement, because you need to reliably detect whether two pieces of code are allowed to run in parallel, or if there's a non-obvious dependency between them that would prevent it (e.g. thread A is about to read memory cell X, is there any way for thread B to write to memory cell X before it yields to the scheduler ?)
- eveningcoffee 11y agoThis code can only work if each call to `process()` is executed atomically, start-to-finish, without another call touching `result` or `left`. In any language but JS, this would be an obvious race condition. But JS guarantees that there will be no concurrent access, and plenty of third-party code relies (perhaps unknowingly) on this serial execution property. Wow, this is very strong guaranty. Thanks for this insight. I do not write code in JS (only small spinets when necessary), so I do not have deep knowledge in it, but it would be really interesting to know where this property is described or what books should one read today to get into JS programming.
- victorNicollet 11y agoNot an easy read, but the ECMAScript specification is very interesting if you have the time: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-execution-contexts http://www.ecma-international.org/ecma-262/6.0/index.html#se... > At any point in time, there is at most one execution context that is actually executing code. > Evaluation of code by the running execution context may be suspended at various points defined within this specification. Once the running execution context has been suspended a different execution context may become the running execution context and commence evaluating its code. Suspending the evaluation context is triggered by executing certain constructs, some of which are obvious (calling a function suspends the caller context until that function returns) and some of which are complex (there's a nice game of context switching whenever generators are involved). The general idea is that the evaluation context decides to be suspended, rather than forced to do so by anything else (like a thread scheduler).