Subject: [Anima] comments on draft-ietf-anima-grasp-api

From: Michael Richardson <[email-masked]>
Date: Tue, 06 Aug 2019 13:24:03 -0400

I read draft-ietf-anima-grasp-api from the expired drafts list.

I think that the event-loop architecture is different than a
polling architecture.  I agree that given an event-loop architecture,
that one can build a polled architecture, but the converse is not true.
The event-loop mechanism needs something to send events, while the polling
system does not.

section 2.3.1.3:
If you are going to insert C structures, why not use a real example?
  https://github.com/PJK/libcbor/blob/master/src/cbor/data.h#L164
  cbor_value -> cbor_item_t

I don't understand what the asa_nonce is for.
Is this something that the underlying GRASP library is supposed to use
internally to sort out which ASA is which?  Maybe this should be
either a UUID, or an opaque type, which might in some cases, be a file
handle, or contain one. (a la FILE *)

2.3.3 Discovery.
  1) I would prefer to be able to ask for the list of cached
     locators for an objective directly.
  2) Rather than flush them explicitely (because there might be
     other ASAs depending upon them), I'd like to do a discovery
     that asks for objectives that are at at most X miliseconds old.
     Flush is therefore X=0.
  3) In both threaded and event-loop situations, I'd like to be able
     have a function called when there are new answers, otherwise,
     I have to poll.
     (And, if a function is called, then the question as to which
     thread does the calling is important; specifically one needs
     to know which other functions one call at that point
     answer may well be none. The answer depends upon how locking
     of structures is done. The answer is easier in event-loop
     version)

2.3.4 Negotiation.
      Since the session_nonce is returned by the function, how
      can the dryrun/run ever be mixed in a single session?  maybe
      I don't know what a session is.
      Ah, it's a value/result parameters.   So, please put it into
      the input section too.

listen_negotiate.
      I think that this call is wrong in both threaded and event-loop
      use.  I think that in threaded version, I really want a new
      thread spawned off that does the right things (negotiate_wait, etc.),
      so I want to provide a function for that thread to run the negotiation.
      In event-loop, I think that I want the same thing, but in the
      function, I can't do synchronous calls, so the function has to
      be called each time.

negotiate_step:
      It says:
         Threaded implementation: Called in the same thread as
         the preceding 'request_negotiate' or 'listen_negotiate', with the
         same value of 'session_nonce'.
      but if it's in the same thread as listen_negotiate(), then I can
      only handle negotiation with a single peer in that thread, I think?
      and I don't think I'd want to call listen_negotiate() for the
      same objective.

negotiate_wait: no idea why I'd use this.

Summary: I do not object to this document going forward as Informational, as
         it represents an explanation of one implementation, and that is
         what Informational is about.
         It would be nice to have the view of multiple implementators, but
         there is no energy for that.
         While I do not object, I do not see great utility in this document.

nits:
  2.3.1.3: s/neg/negotiate/
  I found the "NEG" term in GRASP confusing, because it seems like
  NEGative, rather then NEGotiate.  I'd prefer it was spelt out in
  the API.
  s/dry/dryrun/

--
Michael Richardson <[email-masked]>, Sandelman Software Works
 -= IPv6 IoT consulting =-

---

From: Brian E Carpenter <[email-masked]>
Date: Wed, 7 Aug 2019 14:28:31 +1200

Thanks very much Michael. Some partial responses below.

> I read draft-ietf-anima-grasp-api from the expired drafts list.

Right, the -03 draft expired while we were in Montreal. Our plan
is to make the next update after the two promised reviews arrive.

> The event-loop mechanism needs something to send events, while the polling

My understanding is limited, but the diagram at
https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
seems to say something different: the loop detects events by
polling. (Yes, OK, that's talking about Javascript but the
fundamentals are the same, surely?)

>   cbor_value -> cbor_item_t

Yes, we can look at that. There are various CBOR libraries in C.
 
> I don't understand what the asa_nonce is for.

OK, then we need more text.

> handle, or contain one. (a la FILE *)

Yes, it should probably be opaque. In fact the documentation of the
concrete Python API says so: "Note - the ASA must store the asa_nonce
(an opaque Python object) and use it in every subsequent GRASP call."

>      locators for an objective directly.

OK, I can see that might be useful.

>      that asks for objectives that are at at most X miliseconds old.

Hmm. I think we assumed you would only flush if you had reason to
believe they were stale. But certainly adding an age limit seems
reasonable.

>      have a function called when there are new answers, otherwise,

Right, that's a callback in event loop terminology. It's a matter of
preference; I have an aversion to side effects so I don't like callbacks.
However, you're probably right that it should be an option.

>      of structures is done. The answer is easier in event-loop

Yes; callbacks are a Bad Idea in a multithreaded version.
 
>       Ah, it's a value/result parameters.   So, please put it into

OK will think about that.

>       thread spawned off that does the right things (negotiate_wait, etc.),

You do need a new thread. But I don't have time right now to explain
how that works in my example use cases. And my explanation would
be Pythonesque.

>       function, I can't do synchronous calls, so the function has to

Sure. You have to insert a new event in the loop for each new negotiation.

>       only handle negotiation with a single peer in that thread, I think?

Yes. Threads galore. A new thread for each new negotiation.

>       and I don't think I'd want to call listen_negotiate() for the

Actually that will depend on the use case, but if you do so, you need
locks and atomicity. I put all of that into the prefix assignment demo,
I think.
https://github.com/becarpenter/graspy/blob/master/pfxm3.py 
> negotiate_wait: no idea why I'd use this.

That simply refelects a GRASP feature: tell the other end to wait longer.
>          what Informational is about.

All the same, I'd like to capture as much generality as possible.

>          there is no energy for that.

Yes, that's what we need.

Regards
     Brian

> _______________________________________________
> Anima mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/anima
>

---

From: Michael Richardson <[email-masked]>
Date: Wed, 07 Aug 2019 12:45:46 -0400

> Right, the -03 draft expired while we were in Montreal. Our plan is to
    > make the next update after the two promised reviews arrive.

    >> I think that the event-loop architecture is different than a polling
    >> architecture.  I agree that given an event-loop architecture, that one
    >> can build a polled architecture, but the converse is not true.  The
    >> event-loop mechanism needs something to send events, while the polling
    >> system does not.

    > https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ seems
    > to say something different: the loop detects events by polling. (Yes,
    > OK, that's talking about Javascript but the fundamentals are the same,
    > surely?)

I see some of the confusion.
poll(2) is a poorly named system call (that replaces select(2)), which
retrieves the next event from the kernel.  It doesn't really poll :-)

I think that the important point is that:
1) you can't see events in the queue.
2) you can't ask of an action is done, only find out that it finished.

    > (an opaque Python object) and use it in every subsequent GRASP call."

Good, we agree.
The GRASP library should create and manage these handles.
Nonce is the wrong term and will be confused with the protocol and
cryptographic things; handle is a better term.

    >> 2.3.3 Discovery.  1) I would prefer to be able to ask for the list of
    >> cached locators for an objective directly.

    >> 2) Rather than flush them explicitely (because there might be other
    >> ASAs depending upon them), I'd like to do a discovery that asks for
    >> objectives that are at at most X miliseconds old.  Flush is therefore
    >> X=0.

    > believe they were stale. But certainly adding an age limit seems

The age limit means that I never explicitely flush, thus ASA-1 doesn't mess
with the cache for ASA-2.

    >> have a function called when there are new answers, otherwise, I have
    >> to poll.

    > preference; I have an aversion to side effects so I don't like
    > callbacks.  However, you're probably right that it should be an option.

In a threaded environment, I really want a thread per negotiation.
That means, on the server side (the side giving out resources), that I
need a thread per client, which means something has to spawn off these
threads.

    >> (And, if a function is called, then the question as to which thread
    >> does the calling is important; specifically one needs to know which
    >> other functions one call at that point answer may well be none. The
    >> answer depends upon how locking of structures is done. The answer is
    >> easier in event-loop version)

    > Yes; callbacks are a Bad Idea in a multithreaded version.

Not a bad idea, just an idea that must be clearly defined.

    >> listen_negotiate.  I think that this call is wrong in both threaded
    >> and event-loop use.  I think that in threaded version, I really want a
    >> new thread spawned off that does the right things (negotiate_wait,
    >> etc.),

    > how that works in my example use cases. And my explanation would be
    > Pythonesque.

So the API has to perhaps return something that says to the ASA, "new
negotiation here", rather than attempting to actually ever do anything.

--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        |    IoT architect   [
]     [email-masked]  http://www.sandelman.ca/        |   ruby on rails    [