Skip to content

Instantly share code, notes, and snippets.

@jnthn

jnthn/io.md Secret

Created November 27, 2015 13:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnthn/9d8b2e22882d7f7a871e to your computer and use it in GitHub Desktop.
Save jnthn/9d8b2e22882d7f7a871e to your computer and use it in GitHub Desktop.

Some I/O API issues

There are a few tickets raising intersting issues that I'd like to address before 6.c.

Proc::Async vs. IO::Socket::Async

Ticket: https://rt.perl.org/Ticket/Display.html?id=123949

The first complaint is that Proc::Async has a single method for getting a Supply (stdout, for example) that takes a :bin argument to decide if you get bytes or chars. By contrast, IO::Socket::Async as two methods: bytes_supply and chars_supply. The :bin pattern is common throughout the I/O API, so IP::Socket::Async should adopt it. Further, IO::Handle provides a Supply method that takes a :bin argument. So:

my $s = $sock.Supply;           # replaces $sock.chars_supply
my $s = $sock.Supply(:bin);     # replaces $sock.bytes_supply

The second complaint is that with Proc::Async you have to obtain the supplies before starting the process, but with IO::Socket::Async you can obtain them later. While this is a difference, it's probably the best way, since:

  • When you are listening on a socket for incoming connections, you already have the socket, so there's no chance to take the supply earlier.
  • With processes, obtaining the supplies has a secondary role of indicating what handles to bind when the process is spawned, which has to happen before we spawn it.

So, the current design is probably sensible.

The third complaint is that IO::Socket::Async's listen and connect methods take positional arguments, while IO::Socket::INET has a new method and it takes named arguments. There are a few things at work here:

  • listen and connect on IO::Socket::Async have different return types: the first a Supply of incoming connections, the second a Promise. This is in contrast to working with IO::Socket::INET where the type is consistent. So IO::Socket::Async cannot support a new method sensibly.
  • By contrast, IO::Socket::INET could provide connect and listen methods to serve as alternative constructors. But in both cases you'd be using their results rather differently, so it's not clear this would be more smooth instead of more confusing. It may still be a nicer API.
  • A new method typically does take named arguments.

So, hard to know what to do. Input welcome.

Async surprise?

Ticket: https://rt.perl.org/Ticket/Display.html?id=126425

The ticket complains that it is a bit too surprising that print, say, and write on async things (of note Proc::Async) are asynchronous, and that you may get interleavings of operations that you don't expect visually:

$child.print: "1\n";
$child.kill: SIGINT;
$child.print: "2\n";

You'd have to write:

await $child.print: "1\n";
$child.kill: SIGINT;
await $child.print: "2\n";

We could introduce explicit -async variants:

await $child.print-async: "1\n";
$child.kill: SIGINT;
await $child.print-async: "2\n";

And then implement print as, for example:

method print(::?CLASS:D: |c) {
    await self.print-async(|c)
}

Synchronous socket reading

Ticket: https://rt.perl.org/Ticket/Display.html?id=116288

Ticket: https://rt.perl.org/Ticket/Display.html?id=126315

In async, it's easy: we just throw data as it arrives over the network. With sync, we currently provide:

  • recv
  • read

The tickets are about the semantics of these, with regard to whether the size passed should be interpreted as an upper limit or a target. Proposal:

  • recv will never issue more than one low-level read from a socket, and so the interpretation is "upper bound"; the size is graphemes or bytes depending on whether :bin is passed.
  • read tries to read as many bytes as requested (and is always bytes)

get and lines will naturally read until a line break is there, as today.

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