
Benjamin Franksen wrote:
I'd be careful. Introducing a network connection into the equation makes
object (its methods) susceptible to a whole new bunch of failure modes; think indefinite delays, connection loss, network buffer overflow, etc etc. It may be a mistake to abstract all that away; in fact I am convinced
Isaac Dupree wrote: the that
the old Unix habit of sweeping all these failure modes and potentially long delays under a big carpet named 'file abstraction' was a bad idea to begin with. The ages old and still not solved problems with web browsers hanging indefinitely (w/o allowing any GUI interaction) while name resolution waits for completion is only the most prominent example.
IMO it's just a terribly stupid bug in the best web browsers. Maybe inefficient, poorly, or not-at-all-used multithreading?
Explicitly creating a (system) thread with all the overhead (in computing resources, as well as code complexity) only because the system interface is broken? Yes, of course, necessary, but not nice. An extra parameter for a continuation would be a lot more light-weight and would also make explicit that we must expect the call to be delayed. I think the main reason why systems don't regularly employ this scheme is that it is so tedious to work with closures in low-level languages like C.
"file abstraction" has its points. We just need a (type-level?) clear-to-program-with distinction between operations that may block indefinitely, and operations that have particular bounds on their difficulty. Although, modern OSes try to balance too many things, don't usually make any such hard real-time guarantees, in favor of everything turning out more-or-less correct eventually. Back to "file abstraction" - well, considering the benefits of mounting remote systems as a filesystem. The hierarchy abstraction of the filesystem didn't stay the same performance characteristics... And all kinds of potential problems result too, when the connection breaks down!
Indeed, as I have experienced multiple times: NFS clients completely hanging for minutes, enforcing coffee break for the whole office! Not that I would mind a coffee break now or then, but it tends to happen in the middle of an attempt to fix a critical bug in the production system...
How do you program with all those error conditions explicitly? It is difficult. You need libraries to do it well - and I'm not at all sure whether there exist such libraries yet! I mean, programs are much too complicated already without infesting them with a lot of special cases.
What I would like to have is a clear distinction, apparent in the type, between actions that can be expected to terminate fast and with certainty (apart from broken hardware, that is) and others which are inherently insecure and may involve considerable or even indefinite delays. The latter should accept a continuation argument. However, there is obviously a judgement call involved here. Thus, the system should be flexible enough to allow to treat the same resource either as one or the other, depending on the demands of the application. There may be situations where a name lookup can safely be treated as a synchronous operation (e.g. a script run as a cron job); in other situations one might need to regard even local bus access to some I/O card as asynchronous.
indefinite delays I can create with `someCommand | haskellProgram` too
Yes, user input as well as reading from a pipe should be handled like a network connection: call my continuation whenever input is available.
connection loss Is there a correct way to detect this?
There are many ways, typically involving some sort of beacons. Anyway, if all else fails the operation times out.
I find it rather odd when I lose my IRC connection for a moment and then it comes back a moment later (Wesnoth games are worse, apparently, as they don't reconnect automatically). I often prefer considering them an indefinite delay.
Right: The user (the application) is in the best position to decide how long to wait before an operation times out.
network buffer overflow that is: too much input, not processing it fast enough? (or similar).
Yeah, though usually the other way around, i.e. too much output and the system can't send it fast enough (maybe because the other side is slow in accepting data, or because the connection is bad, or whatever).
Memory size limitations are considerably unhandled in programs of all sorts, not just networked ones, though they(networked) may suffer the most.
It is usually not a problem with modern desktop or server systems, rather with so called 'real-time' OSes, where everything tends to be statically allocated.
We wish we had true unlimited-memory Turing machines :) ...this is possibly the most difficult issue to deal with formally. Probably requires limiting input data rates artificially.
That's what one does (or tries to do, until some arbitrary network problem, ill-configured switch or whatever, slows down the network just a bit more and for just a bit longer than you imagined could happen and the system needs to be rebooted). Anyway, scrap the network buffer overflow, I mentioned it only because we've been bitten by it just today. Cheers Ben