For the past few days I have been experimenting with Isolates, ReceivePort, SendPort and Futures in Dart. I think that I have my brain more or less wrapped around them. It's always the "less" that spells trouble for me.
So tonight I hope to take my Doomsday solution from yesterday and beef it up. As I found out, the 2011 doomsday falls on a Wednesday. I wonder which other years in the 21st century have Wednesday doomsdays.
To answer that question, I am going to spawn yet another isolate whose responsibility it is to spawn yesterday's Doomsday isolate to determine the doomsday of every year in the 21st century. I will the filter out everything but the Wednesdays. What could possibly go wrong?
First up, my new finder-of-doom class:
class DoomsDayFinder extends Isolate { main () { port.receive((century, replyTo) { this.find('Wed', century).then((wednesdays) { replyTo.send(wednesdays); }); }); } }That is not complete yet, but it does sub-class
Isolate
, as an isolate must. It also defines the main()
method that spawn()
will call when the Send/ReceivePorts are ready. Since the ports are ready, I can define the receive()
callback, which will be sent the century being searched.In the callback, I ask to
find()
the Wednesdays in the supplied century. Since I am defining a then()
callback once all the Wednesday are found, the return value of find()
needs to be a future. As I found the other day, a completer is a good mechanism for building futures:class DoomsDayFinder extends Isolate { main() { /* ... */ } find(day, century) { final completer = new CompleterAlso in there is the DoomsDay isolate from yesterday. Inside that poor man's iteration (I do wish Dart supported ranges out of the box), I am going to spawn an isolate for each year, adding the year to the list of matching years if the day is a Wednesday. To find those Wednesdays, I try the following:()
, doom = new DoomsDay() , matching_years = []; for (var i=0; i <100; i++) { // find wednesday doomsdays } return completer.future; } }
class DoomsDayFinder extends Isolate { main() { /* ... */ } find(day, century) { final completer = new CompleterFor the most part, that should work. Except.... I am not completing my future. The future being returned at the end of() , doom = new DoomsDay() , matching_years = []; for (var i=0; i <100; i++) { var year = century + i; doom.spawn().then((port) { port.call({'year':year}).receive((message, replyTo) { if (message == 'Wed') matching_years.add(year); }); }); } return completer.future; } }
find()
will only invoke the next step, the then()
callback, if something tells the completer that it is... complete.Sadly, I can think of no other way to accomplish this than via a tracking variable that counts the number of replies received from the various Doomsday spawn. Once the number of replies reaches 100, then
find()
is complete:class DoomsDayFinder extends Isolate { main() { /*... */ } find(day, century) { final completer = new CompleterEw. That leaves a little to be desired, but it does work:() , doom = new DoomsDay() , matching_years = []; var replies = 0; for (var i=0; i <100; i++) { var year = century + i; doom.spawn().then((port) { port.call({'year':year}).receive((message, replyTo) { replies = replies + 1; if (message == 'Wed') matching_years.add(year); if (replies >= 100) { completer.complete(matching_years); } }); }); } return completer.future; } }
➜ command_line git:(master) ✗ dart isolates03.dart [2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063, 2068, 2074, 2085, 2091, 2096, ](try.dartlang.org)
That's a crazy amount of overhead for a simple calculation. Perhaps tomorrow I will come up with something more realistic. If nothing else, I think I am getting the hang of these beasties. And they're pretty damn fun.
Day #257
Hey Chris, what are you using for your code formatter in your blog? It looks really nice for Dart. :)
ReplyDeleteI'm using google-code-prettyify (http://code.google.com/p/google-code-prettify/). I think it's probably just guessing that I'm writing JS because it doesn't support Dart yet.
ReplyDeleteThanks!
ReplyDelete