This is an interesting thread.  Let me see if I can untangle it enough to glean the understanding I'm looking for.  I believe there is some amount of vagueness on my part which is due to not understanding the correct question to ask nor how to properly phrase the thing.  I think another conceptual problem is that I tend to think API instead of protocol, which can confuse the matter.

Again, the vast bulk of my programming experience has been with TCP/IP and those related RFC's, some of which we ported to DECnet (SMTP comes to mind).

The question here that I'm converging on is, "when do you return from the API call"?  In TCP/IP, I'm not sure it is as well defined as I would like.

A comparison with FTP is somewhat illustrative, although once again, DAP and FTP are vastly different things.  For FTP, the control port is actually running RFC 854 TELNET, so you know you are going to wake up on every line break.  Once negotiated, the data port is a stream of bytes which may or may not have blocking in it.  You wake up early from a read in that case because the sender closes the port at end of file.

Paged file structures completely broke this by holding the data port open, so you have no implied end of file, but have to poll for data, which is disgusting.  That's why I know about PSH because I use it to try to guess end of stream.  It's a hack.

That being said, I think where I got confused was understanding the difference between the various levels of buffering, blocking and enforcing record structure.  It's straightforward enough, but somewhat hairy in places and in others, perhaps unfortunate.  In a transfer, data is buffered up in a linked list (the send queue) and flushed based on a number of criteria.  One example, is the number of files done.  For large directories, this can cause the memory usage to vastly expand as everything is sent at once.  That had caused memory issues, which edit 111 partially fixed (but is kind of a hack, as I recall).

When emptying the send queue, Tops-20 DAP only sets end of record on the last message in the queue, which was confusing.  The receiving DAP appears to have to know that it may get a number of records in one read.  I think what's happening is that Tops-20 DAP is signaling, "I'm done sending you some stuff, I won't send you any more and I'm expecting you to respond"

Again, what's happening here is confusing to me, which indicates I ought review the DAP specification again.  I was going to do that, anyway to break out the flag names (instead of just typing the bits)


On 11/26/22 11:10 AM, Paul Koning wrote:

Indeed, DECnet is a packet service rather than a stream service -- that was the one major design error in TCP.  And there is no such thing as a "push flag".  I don't know why there is in TCP, for that matter.

As for the transmit behavior, strictly speaking the DECnet architecture specs are only protocol specs, not API specs.  There are functions in the descriptive text that look somewhat like an API, but they are intended merely as description and not as suggestions -- let alone prescriptions -- for an API.  For example, it's not likely any real API uses a polled model, as the description does.  Not even PyDECnet, which in many respects does look a fair amount like the model descriptions.

So while it's reasonable to expect that the actual OS API for DECnet transmit corresponds directly to a packet going out right then, I'm not sure you could actually point to DECnet spec text that requires such behavior.  I do expect that everyone does that, with the possible exception of DEC Unix when using "stream mode" sockets.  There would be any good reason to delay sending an offered packet, since there isn't much of anything that could be done differently if one were to do so.  TCP is entirely different, there deferring transmit allows the possible addition of more bytes to the packet.  That's not a possibility in DECnet.

On the subject of completion, that's an API choice.  RSTS does it differently from RSX, its API for transmit means "queue a request for transmission", and the call completes as soon as the message has been accepted into the outbound queue.  Transmission on the wire happens right away if flow control permits, or later if there is no current permission to send.  The ACK from the other end willl stop retransmits and remove the packet from the transmit queue.

	paul