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