-
-
Save DmitrySoshnikov/1274980 to your computer and use it in GitHub Desktop.
class Printer extends Isolate { | |
main() { | |
port.receive((message, replyTo) { | |
if (message == null) port.close(); | |
else print(message); | |
}); | |
} | |
} | |
main() { | |
// first isolate process | |
new Printer().spawn().then((port) { | |
for (var message in ['Hello', 'from', 'other', 'isolate']) { | |
port.send(message); | |
} | |
port.send(null); | |
}); | |
// second isolate process | |
new Printer().spawn().then((port) { | |
for (var message in ['*Hello', '*from', '*other', '*isolate']) { | |
port.send(message); | |
} | |
port.send(null); | |
}); | |
} | |
// Results (WTF?) | |
Hello | |
from | |
other | |
isolate | |
*Hello | |
*from | |
*other | |
*isolate | |
// Why the output is sequential but not parallel? How the Dart's processes' scheduler work? |
Still it seems just a bug for me. Even being in a single (real, OS) thread, cooperative ("green", "light") threads (or "tasks", or "isolates" how they are called here) are usually managed by a scheduler. For example, Erlang also uses "green" lightweight processes and schedules them in parallel. Even in current JS with yield
it's possible to have such cooperative tasks which are executed in parallel by the scheduler (see e.g. this one simple implementation: https://gist.github.com/1127536).
Usually when the spawn
is used it means that something is running in a separate region and in parallel. In other case -- what for do I need to write this useless wrappers with isolate
and spawn
in order just to provide sequential code? Seems just a bug of the current version.
Hello. Here is my try - http://try-dart-lang.appspot.com/s/L5QU
Usually the result is not parallel, but one time (only one) I got the following result:
*Hello
*from
Hello
*other
MT is heavy to test)) - I tried to insert my sleep() method inside Isolate, but t no success.
isopov yes, really strange results. On my machine your tests often do not finish completely -- i.e. only output from first or second process, but sometimes -- both. So, definitely there are still bugs in this module. Thus, this is regardless whether I use your sleep
function or comment it (btw, the sleep
method you wrote is blocking).
This is outside the scope of the current conversation regarding light and heavy isolates. My question is more basic; the syntax is confusing me. What exactly are we passing in as an argument to "then"? I think mostly "(port)" is throwing me off.
new Printer().spawn().then((port) {
for (var message in ['Hello', 'from', 'other', 'isolate']) {
port.send(message);
}
port.send(null);
});
Ahh I see now that its an anonymous function, so once the Isolate is spawned the unnamed functions is called with port as the argument.
This makes no sense. spawn
indicates there's an internal scheduler involved, which would make me believe the loops run in parallel causing results not to be in a sequence.
FreakTheMighty, right, it's an anonymous callback function.
kaisellgren, yes, the same I thought (after programming in Erlang and having implemented similar scheduled processes in JS with yield
-- https://gist.github.com/1127536). However, after analyzing the source code of Dart's runtime library, I figured out that it's a design decision caused by impossibility of implementation of such parallel processes with using just setTimeout
scheduling (you may check btw, my similar setTimeout
processes -- https://gist.github.com/1103751). That is, callback process function should run to completeness and can't be interrupted in the middle. And exactly this cases sequential execution, but not parallel.
Recently I discussed the topic in Dart's mailing list: http://bit.ly/n3IUiT
@DmitrySoshnikov: as far as I know, most ES engines do not support yield
, except *Monkey. Therefore, I also believe the Dart engineers decided it is not possible to support "parallel processes" in transcompiled JS and this is the outcome :(. By the way, I like https://gist.github.com/1127536, did something similar once as well :)
Based on my 30 minutes of reading the tech overview, it looks like light Isolate classes are spawned on the same thread as the main program, so this code will run sequentially based on the order of creation of each Isolate (which should also be sequential considering the speed of execution). The then() method is simply a promise that you are placing on each Printer object to execute the loop as soon as the Isolate is spawned.