Paul Cochrane wrote:
Therefore, I thought it'd be a good idea to stimulate some discussion on list, so that something can be distilled from this to help out our architect and those brave enough to implement the design :-)
Excellent. Many thanks.
=item * In the Composition subsection of the Implementation section there are the sentences: To find an I/O function, the layer stack is searched downwards until a non-NULL function pointer is found for that particular slot. This implementation will be replaced with a composition model. Has the composition model been designed? Or has it been implemented? Are we still left with the stack-based implementation?
I'm currently finishing off PDD 17, which specifies C-level roles. So, it hasn't been implemented yet.
=item * Later, under the Status Object PMC API there is the comment: Returns an integer status for the status object, 1 for successful completion, -1 for an error, and 0 while still running. [Discuss: This is largely to preserve current expectations of -1 for an error. If we move away from that, is there a better representation?] We should discuss if there is a better representation and make the relevant design decision.
I'll leave it open for comments. I'm happy to do away with integer status values entirely if we have a workable alternative.
=item * Under "Retrieving and setting stream properties" there is a paragraph about the C<poll> opcode which states: Polls a stream or socket object for particular types of events (an integer flag) at a frequency set by seconds and microseconds (the final two integer arguments). [At least, that's what the documentation in src/io/io.c says. In actual fact, the final two arguments seem to be setting the timeout, exactly the same as the corresponding argument to the system version of C<poll>.] What does io.c actually do? What should it do? Are the tests written for the "implemented" behaviour, or for the "documented" behaviour?
I'm mostly interested in the question of what it *should* do. (Thoughts based on experience or speculation welcome.)
=item * There are three deprecated opcodes mentioned: C<write>, C<get_fd>, and C<pioctl>. Have we removed these yet? Are they listed as deprecated? Should they be deprecated?
They can be listed as deprecated now, with removal pending a full implementation of PDD 22.
=item * Under "Filesystem Opcodes" there is a large comment about possibly moving these opcodes onto methods of the ParrotIO object. We should really discuss this and make a decision/come to a consensus on that point.
The decisions will be made on a case-by-case basis, so pitch in votes for particular opcodes you want to keep as opcodes or are happy to demote (promote?) to methods.
Within the same subsection there is the text: C<stat> retrieves information about a file on the filesystem. It takes a string filename or an integer argument of a UNIX file descriptor [or an already opened stream object?] Should we be using an already-opened stream object? This point needs discussion.
A "stream object" is just a filehandle. And I think filehandles should be able to stat information about their corresponding files.
=item * Under "Network I/O Opcodes" there is the comment: Most of these opcodes conform to the standard UNIX interface, but the layer API allows alternate implementations for each. [These I'm also considering moving to methods in a role for the ParrotIO object. Keep 'socket' as an opcode, or maybe just make 'socket' an option on creating a new ParrotIO object.] Again, should these opcodes be moved to methods in a role for the ParrotIO object? What are the pros and cons of such a decision? Have we already done this? Again, I just want to get discussion going and a consensus (or executive) decision made.
Again, a case-by-case decision. The pro of providing opcodes in addition to methods is just a matter of syntactic sugar. All the opcodes do is call the relevant methods on the IO object, sometimes with a little preprocessing on the arguments.
In general, I'm in favor of providing opcodes when they do a significant amount of preprocessing on the arguments (since they're adding the value of a simpler interface), and against providing opcodes that are nothing more than a pass-through to a method call.
=item * Error Handling Currently some of the networking opcodes (C<connect>, C<recv>, C<send>, C<poll>, C<bind>, and C<listen>) return an integer indicating the status of the call, -1 or a system error code if unsuccessful. Other I/O opcodes (such as C<getfd> and C<accept>) have various different strategies for error notification, and others have no way of marking errors at all. We want to unify all I/O opcodes so they use a consistent strategy for error notification. How should we unify all I/O opcodes?
Pick one of: throw an exception on error, return a status object that can be queried for an error, or return an integer status code.
The status object is preferred for async I/O operations, since the status object allows for tracking state changes as needed.
=item * Within the same section is the comment: [Discuss: should synchronous operations take the same error handling strategy as asynchronous ones?] Some form of discussion should take place here to pick apart the issues (if any) and find a design to follow.
The conclusion after a good bit of discussion earlier this year was that returning a status object for every synchronous operation was far too heavyweight. Exceptions don't get a high vote as an alternative, but that's largely because the current prototype implementation of exceptions is less-than-usable. Integer status codes are another alternative.
Ok, I think that's it for this PDD. I'm going to hold off sending more such emails until people think this is a good idea or not. If so, I've edited a few more of the other PDDs and I can summarise what looks to me like should be discussed so that we can firm up the design a bit more. Hopefully this will help us get to 1.0 that bit faster! If you got this far through the email - thanks!
Thanks for the helpful discussion starter. Allison