we promised that the dart:io APIs would change over time. They
just did: https://chromiumcodereview.appspot.com/9500002/
Short summary of changes:
One-shot methods now take their callback as an argument:
Instead of
var f = new File('myfile.txt');
f.exists();
f.existsHandler = (result) {
// do stuff.
};
write
var f = new File('myfile.txt');
f.exists((result) {
// do stuff.
});
For active objects such as streams that emit events, the event
handlers have changed names from eventHandler to onEvent:
Instead of
stdin.dataHandler = () {
// do stuff.
};
write
stdin.onData = () {
// do stuff.
};
Cheers, -- Mads
The *Sync names are actually intentionally obtuse (and are used by
node.js as well). :-)
Basically, the Sync part of the name is a warning that you probably do
not want to use them. Whenever you call a method that is called
something ending in Sync you know that you are blocking the main
thread which is a Bad Thing for scalability. It is fine for simple
scripts, it should be avoided for servers that should scale to deal
with many requests.
Cheers, -- Mads
why fooSync doesn't register a callback, block the current lightweight
isolate
(not the thread) and let the current thread serve another lightweight
isolate.
I think Dart IO should be designed to not let users to be able to block
a thread
(and not be able to even control threads).
A server should first create a pool of threads with as many thread as
core (+/- 1).
Each time a new connection is accepted, the server should create a
lightweight isolate
and push it into a waiting queue.
Each thread from the pool, should dequeue the lightweight isolate and
run it,
if this isolate do a blocking operation, it should register the
operation asynchronously
and when the event arrive, the lightweight isolate should be enqueue again.
so when a thread should try to run it, the lightweight isolate will be
resumed.
Users should only control isolates not threads.
R�mi
I'm not sure I understand. It is already the case that users do not
have control over threads. Asynchronous operations lets you do a lot
with only one thread. When that one thread is not enough you can turn
to isolates.
Cheers, -- Mads
As a user I can create lightweight isolate or heavyweight isolate.
I may be wrong but for me an heavyweight isolate is a thread.
What I'm trying to say is that the user should just do IOs
and that if the IO call is done in a server, it should be an async call
that stop the isolate and resume it when the IO is done and
that do classical blocking IO in a script (if there is only one isolate).
R�mi
On 03/01/2012 02:59 PM, Mads Ager wrote:
Rémi
we did consider going with object.on.event.add(handler). However,
having a collection of handlers for dart:io events usually doesn't
make sense. Then you are down to object.on.event = stuff. At that
point I think it is better to just have object.onEvent = stuff.
Your point about error callbacks is a good one. For now we decided
that having it on the object is good enough. Once you get to having
multiple callbacks for one method things get messy with passing in
callbacks. Let's see where this takes us. I'm not against changing all
of this again if it turns out that something else would be better. :)
One of the advantages of explicitly passing in the callback to
single-shot methods is that you get a very tight coupling between the
call and its continuation. You *have to* specify what happens next and
therefore it is hard to use the API incorrectly. Futures doesn't give
you that because you can forget to do the ".then(continuation)" part.
Cheers, -- Mads
Remi,
Regardless of how threads are mapped to isolates calling a *Sync
operation will suspend your isolate from handling any other requests.
That is what Mads referred to as a "Bad Thing for scalability".
In any case how threads are assigned to isolates is an implementation
detail and is orthogonal to this discussion.
-Ivan
Hi Sean,
we did consider going with object.on.event.add(handler). However,
having a collection of handlers for dart:io events usually doesn't
make sense.
Then you are down to object.on.event = stuff. At that
point I think it is better to just have object.onEvent = stuff.
Your point about error callbacks is a good one. For now we decided
that having it on the object is good enough. Once you get to having
multiple callbacks for one method things get messy with passing in
callbacks.
Let's see where this takes us. I'm not against changing all
of this again if it turns out that something else would be better. :)
One of the advantages of explicitly passing in the callback to
single-shot methods is that you get a very tight coupling between the
call and its continuation. You *have to* specify what happens next and
therefore it is hard to use the API incorrectly. Futures doesn't give
you that because you can forget to do the ".then(continuation)" part.
Another option would be to combine the success and error callbacks by adding an optional `String error` parameter to the success callback signatures:open(void success(bool exists, [String error]), [FileMode mode]);
// returns null iff success is null
Then you are down to object.on.event = stuff. At that
point I think it is better to just have object.onEvent = stuff.I don't have much of a preference between `object.on.event` and `object.onEvent`, I just think it ought to be consistent between dart:html, dart:io, etc.