Re: IO Multiplexing

2010-11-13 Thread Ben Goldberg
On Nov 12, 2:21 pm, stefa...@cox.net (Stefan O'Rear) wrote:
 On Thu, Nov 11, 2010 at 05:47:46PM -0800, Ben Goldberg wrote:
  I would like to know, is perl6 going to have something like select
  (with arguments created by fileno/vec), or something like IO::Select
  (with which the user doesn't need to know about the implementation,
  which happens to be done with fileno/vec/select), or only an event
  loop.

 I will be unhappy if Perl 6 doesn't provide all three.  However, the
 spec in question doesn't really exist.  The IO synopsis is garbage
 and should be deleted and rewritten from scratch by someone who knows
 what they're talking about.

  I would recommend that there NOT be any sort of fileno exposed to the
  user, unless he goes out of the way to get it -- any function (in
  particular, posix functions) should simply take a perl filehandle, and
  that function in turn would pull out the fileno (or fail
  appropriately, if the filehandle doesn't have a fileno).  If users
  want to know if filehandles correspond to the same underlying file,
  then there could be a method -- perhaps $fh.uses_same_desciptor($fh2),
  or somesuch.

 This goes without saying.  One caveat - it should be possible to pass
 integer file descriptors.

For functions in the posix module, sure; but for everywhere else, if
the
user wants to pass integer file descriptors to a function which is
expecting
an IO object, maybe not.  But it should be easy (maybe even trivial)
to create a new IO object from an integer file descriptor.

  If there's a select() builtin (and I'd much rather that there not be
  -- it should be hidden away in a class, like perl5's IO::Select), I'd
  very much hope that it would take and return Sets of filehandles, not
  vec packed strings.  I'd prefer there not be one[**]

 Absolutely not.  TIMTOWDI.  There will be a select() function (in
 the POSIX module, not the default namespace!), and it will take
 parameters as close as possible to POSIX.1's definition.  Perl without
 system calls is not Perl.

 I'm totally fine with discouraging casual use, though, which is why
 it shouldn't be in the default namespace.

+1 :)

  If there's something like perl5's IO::Select, it should be able to
  just work regardless of whether the perl filehandles are sockets,
  regular files, or user-created pure-perl filehandles (which might
  never block, or which might use one or more normal filehandles
  internally, which in turn might potentially block).  This is what I'd
  prefer.

 That is a good doctoral thesis topic.

Require that IO objects provide a uniform interface by means of which
the
multiplexer object can determine blockability.

Any user-defined IO handle which doesn't wait on external events will
never
block, and it can say so.

A user defined IO handle which waits on a built in IO handle can say
what
handle it will need to wait upon, and what operation it will need to
wait for.

A user defined IO handle which waits for a signal can say what signal
it
is waiting for.

A user defined IO handle which waits for a condition variable can say
what
variable it's waiting on, and what kind of state change it's looking
for.

Given the complexity of looking for other things (in particular, IPC
that
doesn't use streams), the simple solution is to require that they
write a
class for it, and have that class (internally) create a kernel thread
which
will block on the desired IPC, and write a byte to a pipe... this
allows
the perl level IO handle to say to the multiplexer that it's waiting
on
the read end of that pipe.  This is roughly the same technique that we
would use to safely detect signals.

  Lastly, if perl6 has an efficient enough built-in event loop, and
  sufficiently lightweight coroutines (or maybe I should say fibers?),
  then we might not need to have any kind of explicit multiplexing.

 TIMTOWDI.  Perl without system calls is not Perl.

Yeah, but if it's more efficient to not directly use those
system calls, then what's the point of having them?

  For example, any time user code does a read operation on a handle that
  isn't (from the user code's point of view) in nonblocking mode, the
  filehandle implementation would tell the the event loop to yield to it
  when the handle becomes readable, then it would yield to the event
  loop, then (once it gets back control) read from the handle.[*]

 This is why S16 is junk - too much blue-sky thinking, not enough
 pragmatism and practical experience.

S16 has almost nothing in it about actual IO (it does talk about how
STDIN, STDOUT, STDERR, and ARGV will be replaced with $*IN, $*OUT,
$*ERR, and $*ARGFILES, and how they will be dynamically overrideable).

Did you mean to say S32::IO?

While S32::IO describes what methods and roles IO objects will have/
do,
the only thing it says about multiplexing is that both of perl5's
select()
operators will disappear.

It's fairly obvious that select() / select(EXPR) will be replaced with
the
dynamically overrideable $*IN.  (Not that 

Re: IO Multiplexing

2010-11-13 Thread Stefan O'Rear
On Fri, Nov 12, 2010 at 06:59:59PM -0800, Ben Goldberg wrote:
(snip plea to paint the bikeshed fuchsia)

The design of the I/O system will be chosen by the first person to implement
it.  If you want any say in the matter, you need to be that person.  Bonus
points if you also port at least one app to prove that your system is usable.

-sorear


signature.asc
Description: Digital signature


IO Multiplexing

2010-11-12 Thread Ben Goldberg
I would like to know, is perl6 going to have something like select
(with arguments created by fileno/vec), or something like IO::Select
(with which the user doesn't need to know about the implementation,
which happens to be done with fileno/vec/select), or only an event
loop.

I would recommend that there NOT be any sort of fileno exposed to the
user, unless he goes out of the way to get it -- any function (in
particular, posix functions) should simply take a perl filehandle, and
that function in turn would pull out the fileno (or fail
appropriately, if the filehandle doesn't have a fileno).  If users
want to know if filehandles correspond to the same underlying file,
then there could be a method -- perhaps $fh.uses_same_desciptor($fh2),
or somesuch.

If there's a select() builtin (and I'd much rather that there not be
-- it should be hidden away in a class, like perl5's IO::Select), I'd
very much hope that it would take and return Sets of filehandles, not
vec packed strings.  I'd prefer there not be one[**]

If there's something like perl5's IO::Select, it should be able to
just work regardless of whether the perl filehandles are sockets,
regular files, or user-created pure-perl filehandles (which might
never block, or which might use one or more normal filehandles
internally, which in turn might potentially block).  This is what I'd
prefer.

Lastly, if perl6 has an efficient enough built-in event loop, and
sufficiently lightweight coroutines (or maybe I should say fibers?),
then we might not need to have any kind of explicit multiplexing.

For example, any time user code does a read operation on a handle that
isn't (from the user code's point of view) in nonblocking mode, the
filehandle implementation would tell the the event loop to yield to it
when the handle becomes readable, then it would yield to the event
loop, then (once it gets back control) read from the handle.[*]

This provides lots of convenience, but it would resemble Java IO
before the NIO -- except with one fiber per handle instead of one
thread per handle.  Coroutines/green threads/fibers are much lighter
weight than real threads, but often aren't as fast as a well-written
select() loop specially written for the user's task.

Thus, I'd hope for perl6 to have an IO::Select, and automatically-
yielding [*] blocking IO, and not have a select() builtin.  [**]

[*] This is a simplification:
A) If a user explicitly marks a filehandle as not yielding to other
coroutines, it would do a blocking read (or whatever) instead of going
through the event loop rigmarole.
B) If perl6 was compiled with an asynchronous IO library (or is on
windows and is not using stdio and has (Read|Write)FileEX support),
then it might start the Async IO operation, tell the event loop to
wake it when the operation completes, then yield to the event loop.
C) Depending on circumstances, it *may* be more efficient to have the
event loop itself do the reading or other IO itself, and schedule the
fibers for which the IO was done, than to have the fibers do the IO.
TMTOWTDI.  This would be especially important if perl is compiled with
async IO -- the event loop might first wait for the fds to be readable/
etc, *then* start the async IO for those fds, then schedule the fibers
for which the performed IO has completed, thus minimizing the number
of outstanding async io operations.

[**] The main reason I'd prefer that perl6 not have a select() builtin
is that every time it's called perl would need to convert user-level
Sets of filehandles into the underlying implementations' versions of
them (fd_sets on unixy, fd_sets and/or an event queue handle on
windows), and then back to perl Set objects, and free up the
implementation version of the filehandle set... this is inefficient.

A well written IO::Select-like object could create (potentially empty)
versions of the OS's set of filehandles when it's created, add to that
set as needed, and NOT destroy that implementation-specific set until
the IO::Select object itself is destroyed.  Perl5's IO::Select does
this with the packed bitsets that it creates to pas to select.  It
could do improve it's efficiency by using fd_sets instead of
bitstrings, and not use the perl select(), but the C select(2)
instead.

Better still would be epoll.  In this case, avoiding repeated setup
makes an object multiplexer model enormously more efficient than
something like select().

Similarly, on windows, if we WSAEventSelect or WSAAsyncSelect to
create readability/ writability/ etc events for IO operations we want
to wait on, and [WSA]WaitForMultipleEvents as the blocking operation,
then having an object multiplexer (which keeps events between one call
to the next) is far better than a simple subroutine (which needs to
cancel those events after it blocks and before it returns).



Re: IO Multiplexing

2010-11-12 Thread Moritz Lenz

Hi,

Am 12.11.2010 02:47, schrieb Ben Goldberg:

I would like to know, is perl6 going to have something like select
(with arguments created by fileno/vec), or something like IO::Select
(with which the user doesn't need to know about the implementation,
which happens to be done with fileno/vec/select), or only an event
loop.


The IO specification for Perl 6 is very suboptimal as is. On the one 
hand it's over-engineered, in that there's a plenthora of confusing 
roles that makes it hard to do anytyhing. On the other hand it's 
under-engineered in the sense that it doesn't even talk about 
non-blocking IO yet.


If that's a topic you know and care about, I'd welcome any contributions 
you can make to the spec. Don't be scared, it's just a collection of 
text documents :-)
So if you send me your github ID (get one if you don't have one), I'll 
give you commit access.



I would recommend that there NOT be any sort of fileno exposed to the
user, unless he goes out of the way to get it -- any function (in
particular, posix functions) should simply take a perl filehandle, and
that function in turn would pull out the fileno (or fail
appropriately, if the filehandle doesn't have a fileno).  If users
want to know if filehandles correspond to the same underlying file,
then there could be a method -- perhaps $fh.uses_same_desciptor($fh2),
or somesuch.


Agreed. A higher level interface than POSIX would be a good default, IMHO.


If there's a select() builtin (and I'd much rather that there not be
-- it should be hidden away in a class, like perl5's IO::Select), I'd
very much hope that it would take and return Sets of filehandles, not
vec packed strings.  I'd prefer there not be one[**]


As I tried to imply above, you can shape Perl 6 if you want. If you 
supply a superior alternative to select/IO::Select, people will happily 
implement and use it.



Lastly, if perl6 has an efficient enough built-in event loop, and
sufficiently lightweight coroutines (or maybe I should say fibers?),
then we might not need to have any kind of explicit multiplexing.


I'm not sure if the question about having an event loop is fully 
answered; there was some discussion about it in relation to concurrency 
and feed operators, but I didn't follow them too closely.


We certainly have coroutines in the form of gather/take.

I'm sorry for not commenting more on your actual proposals, which is 
mostly due to my lack of real-world experience with non-blocking IO.


Cheers,
Moritz


Re: IO Multiplexing

2010-11-12 Thread Stefan O'Rear
On Thu, Nov 11, 2010 at 05:47:46PM -0800, Ben Goldberg wrote:
 I would like to know, is perl6 going to have something like select
 (with arguments created by fileno/vec), or something like IO::Select
 (with which the user doesn't need to know about the implementation,
 which happens to be done with fileno/vec/select), or only an event
 loop.

I will be unhappy if Perl 6 doesn't provide all three.  However, the
spec in question doesn't really exist.  The IO synopsis is garbage
and should be deleted and rewritten from scratch by someone who knows
what they're talking about.

 I would recommend that there NOT be any sort of fileno exposed to the
 user, unless he goes out of the way to get it -- any function (in
 particular, posix functions) should simply take a perl filehandle, and
 that function in turn would pull out the fileno (or fail
 appropriately, if the filehandle doesn't have a fileno).  If users
 want to know if filehandles correspond to the same underlying file,
 then there could be a method -- perhaps $fh.uses_same_desciptor($fh2),
 or somesuch.

This goes without saying.  One caveat - it should be possible to pass
integer file descriptors.

 If there's a select() builtin (and I'd much rather that there not be
 -- it should be hidden away in a class, like perl5's IO::Select), I'd
 very much hope that it would take and return Sets of filehandles, not
 vec packed strings.  I'd prefer there not be one[**]

Absolutely not.  TIMTOWDI.  There will be a select() function (in
the POSIX module, not the default namespace!), and it will take
parameters as close as possible to POSIX.1's definition.  Perl without
system calls is not Perl.

I'm totally fine with discouraging casual use, though, which is why
it shouldn't be in the default namespace.

 If there's something like perl5's IO::Select, it should be able to
 just work regardless of whether the perl filehandles are sockets,
 regular files, or user-created pure-perl filehandles (which might
 never block, or which might use one or more normal filehandles
 internally, which in turn might potentially block).  This is what I'd
 prefer.

That is a good doctoral thesis topic.

 Lastly, if perl6 has an efficient enough built-in event loop, and
 sufficiently lightweight coroutines (or maybe I should say fibers?),
 then we might not need to have any kind of explicit multiplexing.

TIMTOWDI.  Perl without system calls is not Perl.

 For example, any time user code does a read operation on a handle that
 isn't (from the user code's point of view) in nonblocking mode, the
 filehandle implementation would tell the the event loop to yield to it
 when the handle becomes readable, then it would yield to the event
 loop, then (once it gets back control) read from the handle.[*]

This is why S16 is junk - too much blue-sky thinking, not enough
pragmatism and practical experience.

 This provides lots of convenience, but it would resemble Java IO
 before the NIO -- except with one fiber per handle instead of one
 thread per handle.  Coroutines/green threads/fibers are much lighter
 weight than real threads, but often aren't as fast as a well-written
 select() loop specially written for the user's task.
 
 Thus, I'd hope for perl6 to have an IO::Select, and automatically-
 yielding [*] blocking IO, and not have a select() builtin.  [**]

TIMTOWDI.

 [*] This is a simplification:
 A) If a user explicitly marks a filehandle as not yielding to other
 coroutines, it would do a blocking read (or whatever) instead of going
 through the event loop rigmarole.
 B) If perl6 was compiled with an asynchronous IO library (or is on
 windows and is not using stdio and has (Read|Write)FileEX support),
 then it might start the Async IO operation, tell the event loop to
 wake it when the operation completes, then yield to the event loop.
 C) Depending on circumstances, it *may* be more efficient to have the
 event loop itself do the reading or other IO itself, and schedule the
 fibers for which the IO was done, than to have the fibers do the IO.
 TMTOWTDI.  This would be especially important if perl is compiled with
 async IO -- the event loop might first wait for the fds to be readable/
 etc, *then* start the async IO for those fds, then schedule the fibers
 for which the performed IO has completed, thus minimizing the number
 of outstanding async io operations.
 
 [**] The main reason I'd prefer that perl6 not have a select() builtin
 is that every time it's called perl would need to convert user-level
 Sets of filehandles into the underlying implementations' versions of
 them (fd_sets on unixy, fd_sets and/or an event queue handle on
 windows), and then back to perl Set objects, and free up the
 implementation version of the filehandle set... this is inefficient.
 
 A well written IO::Select-like object could create (potentially empty)
 versions of the OS's set of filehandles when it's created, add to that
 set as needed, and NOT destroy that implementation-specific set until
 the 

Re: IO Multiplexing

2010-11-12 Thread Patrick R. Michaud
On Fri, Nov 12, 2010 at 11:21:10AM -0800, Stefan O'Rear wrote:
 TIMTOWDI.  Perl without system calls is not Perl.

+1

 This is why S16 is junk - too much blue-sky thinking, not enough
 pragmatism and practical experience.

Agreed.

 Forbidding things out of idealistic concerns like API purity is not
 the Perl way.

+1

Pm


Re: IO Multiplexing

2010-11-12 Thread Leon Timmermans
On Fri, Nov 12, 2010 at 8:21 PM, Stefan O'Rear stefa...@cox.net wrote:
 This goes without saying.  One caveat - it should be possible to pass
 integer file descriptors.

Integer file descriptions should exist in the POSIX module, just like
Win32 handles should exist in the Win32 module, but they don't have a
place in the standard IO. That said, some kind of cross-platform
opaque type for low level IO handles may be useful, if only for
comparisons.

 Absolutely not.  TIMTOWDI.  There will be a select() function (in
 the POSIX module, not the default namespace!), and it will take
 parameters as close as possible to POSIX.1's definition.  Perl without
 system calls is not Perl.

I agree.

 TIMTOWDI.  Perl without system calls is not Perl.

True, but those other ways don't necessarily have to be part of the
standard IO, or even the core.

Leon