On 2024-06-18 17:30, Paul Koning wrote:
On Jun 18, 2024, at 11:20 AM, Johnny Billquist
<bqt(a)softjar.se> wrote:
On 2024-06-18 16:00, Paul Koning wrote:
On Jun
17, 2024, at 9:54 PM, Johnny Billquist <bqt(a)softjar.se> wrote:
On 2024-06-17 22:44, Paul Koning wrote:
>> On Jun 16, 2024, at 7:03 PM, Johnny Billquist <bqt(a)softjar.se> wrote:
>>
>> On 2024-06-16 22:40, Paul Koning wrote:
>>>> On Jun 16, 2024, at 4:36 PM, Keith Halewood
<Keith.Halewood(a)pitbulluk.org> wrote:
>>>>
>>>> I approached this from VMS task communication. On a VMS host, I can write
a command procedure and create an object definition, say XXX, to output some data to
SYS$NET then refer to it remotely with something like
>>>> TYPE node::"=XXX"
>>>> This works quite well without the need for the caller to send something
first. I had hoped this would be the case with PyDECnet too.
>>>> Is there any way of making a conn.accept() wait for the state change?
>>> I could change the code to implement queueing until the state changes to
RUN.
>>
>> Or you could not return from the accept until the state change to run?
> Possible, but currently none of the "send" type API calls in PyDECnet do
any waiting. They either accept or reject the request, and if accepted they set it in
motion, but none wait for it to finish (for some definition of "finish").
Do you consider "accept" to be a "send" type call?
Yes,
because it sends a Connect Confirm message to the originator.
Hmm. Seems like this can degenerate into every call is a "send" type. Receive
will cause an ACK. Send, Connect, Conncect Confirm, Reject, Close, and so on all cause a
send. At least under RSX, I think the ACK only happens when the receiver have received the
message.
I meant a packet carrying application payload.
Ah. Ok.
But you still have state changes based on packet with no payload. It's
just that calls are sortof not related to state changes then.
But I do think
the states would/should be triggered by the appropriate call, or received packet.
I would not expect a connect to complete until the accept have happened on the other side
(or rejected). So I would think it's "waiting" no?
That's one design model, and it's a perfectly reasonable one, but it's not
the model I used.
Hmm, looking below, it seems a bit more mixed?
So with
accept, it wouldn't finish until the ACK comes back. Sortof the same thing...
Anyway, I
do consider it to be a bit broken if, after the accept, you have some indeterminate time
when before you can call send. And I would hope you'd agree that this is a bit of a
headache for anyone using the API. Peronally, I would probably consider the accept to not
have completed until I can send data on the connection.
Fair enough. As I said, I
modeled the PyDECnet API on the architecture spec conceptual API (apart from polling). So
none of the sending calls wait for delivery. That's also the easiest to implement,
obviously.
But in that case I wonder how you deal with connect. Because the connection is not
actually established until it has been accepted, and any sends before that point should
also not be possible.
Correct. And the answer is the same as with accept: if you issue connect and then
immediately a data send, you get WrongState. The connect API creates a connection object,
builds the Connect Initiate message, and sends it. That's all it does; retransmits
and the processing of accept or reject happen afterwards.
But until you get an accept or reject, you don't know if it's even ok to
send packets, so it would be crazy to just allow the program to continue
before it have received the conncect confirm or reject, which in
themselves also carry data that is related to the connect request, and
which I would expect a caller to be able to read out the data of
immediately after the connect call completes.
I will look at a friendlier API that does implement
waiting for the cases where there is a state change and the next API call is going to need
that state. Most likely I'll do that only in the "Connectors" API, not in
the module one. The reason is that the module API lives right inside PyDECnet, so any
kind of waiting is more problematic. Most applications can be done just as well using the
connectors API, with the application running as a separate process. The management
applications (NML and the event sender) do need to be modules, obviously, but mirror and
FAL and the like don't.
You know your implementation and its innards... I'm just reflecting on how I would
expect the API to work.
Actually, I had forgotten how the "connectors" API works. It already does the
"wait for accept/reject" thing on a Connect request. But it doesn't have
the equivalent on the accept request, mostly because there isn't a response message
there (the ACK doesn't count, it's handled inside NSP). I can add a
pseudo-message to the underlying machinery for reporting state changes, and then wait for
that in the accept call. A state change "message" would make sense anyway.
Hmm. So you are in fact delaying the return from the connect call. That
sounds good. Now you just need to do the same for the accept. And I'd
say it should be tied into the state change. If you need some
pseudomessage to make it easy to implement, I think that would be
perfectly fine. Not something anyone on the outside would notice anyway.
Aren't there other state changes you should do things on as well? If a
link is lost, NSP will retransmit and eventually time out. If the
application is trying to read, that read should then return an error
when the state change, right? How is that handled then? (Just the first
case that popped into my head.)
Johnny
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: bqt(a)softjar.se || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol