Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Created October 10, 2011 09:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmitrySoshnikov/1274980 to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/1274980 to your computer and use it in GitHub Desktop.
Dart's isolate test
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?
@stevebrownlee
Copy link

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.

@DmitrySoshnikov
Copy link
Author

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.

@isopov
Copy link

isopov commented Oct 11, 2011

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.

@DmitrySoshnikov
Copy link
Author

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).

@FreakTheMighty
Copy link

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);
});

@FreakTheMighty
Copy link

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.

http://www.dartlang.org/articles/idiomatic-dart/

@kaisellgren
Copy link

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.

@DmitrySoshnikov
Copy link
Author

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

@kaisellgren
Copy link

@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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment