[nanomsg] Re: async aio framework exposed to apps in nng

  • From: Michael Powell <mwpowellhtx@xxxxxxxxx>
  • To: "nanomsg@xxxxxxxxxxxxx" <nanomsg@xxxxxxxxxxxxx>
  • Date: Thu, 26 Oct 2017 14:05:46 -0400

On Thu, Oct 26, 2017 at 2:03 PM, Garrett D'Amore <garrett@xxxxxxxxxx> wrote:

The “aio” should be thought of as “owing” the associated message once any
operation is started.  That ownership continues until either the *socket*
takes ownership (as part of a successful send), or the operation fails in
which case the user-supplied callback can get the message back from the aio
with nng_aio_get_message().

Fair enough. I was thinking that was the case and just wanted to clarify.

Thanks!

On Thu, Oct 26, 2017 at 11:00 AM Michael Powell <mwpowellhtx@xxxxxxxxx>
wrote:

On Thu, Oct 26, 2017 at 1:50 PM, Garrett D'Amore <garrett@xxxxxxxxxx>
wrote:
Sorry, forgot to address the timed wait thing for aio_stop.

You don’t want timed wait.  Really.  If you want a time out, set it on
the
aio before submitting the operation.  The main use case for
nni_aio_wait()
is to concretely block pending completion of the operation (or
cancellation
or timeout).  Having a timed nni_aio_wait() would be kind of useless,
because the AIO would be in an indeterminate state at the end of that
call
(at least if the timer expired).

The way message ownership works is that it kind of follows the AIO.  The
caller of nng_send_aio() give the message to the socket.  If the
operation
succeeds (determined in the callback with nng_aio_result(), then the
socket
has taken the message.

If however the operation fails or gives back a non-zero error (e.g. due
to
cancellation or timeout), then the message should be taken from the aio
(or
if a reference was kept from the send it can be used), and the
caller/submitter has the responsibility to either free it, or do
something
else (such as try submitting it again, or submitting it to another
socket,
or whatever.)

The semantic here is always that the “socket” takes ownership on
successful
send, and does not take ownership on failure.  On receive, the socket
makes
a new message and gives it to the user.

Right, but from the perspective of the AIO only?

Notwithstanding Socket send/receive semantics. I've comprehended that
much. What I'm after is Socket operation agnostic semantics here.

Remember from the AIO perspective, in and of itself, it has no way of
knowing "what" is going to be asynchronous. Nor should it, in my
opinion.

So, in other words, "setting" the AIO message effectively transfers
ownership into the AIO?

Whereas, "getting" the AIO message effectively transfers ownership
back out of the AIO?

If that's at all confused, one likely scenario is that the message
curator inadvertently "frees" the message that it got.

Thanks!

On Thu, Oct 26, 2017 at 10:44 AM Michael Powell <mwpowellhtx@xxxxxxxxx>
wrote:

On Wed, Oct 25, 2017 at 9:43 PM, Garrett D'Amore <garrett@xxxxxxxxxx>
wrote:
(This is only for nng, not available for legacy nanomsg.)

I just pushed nng bug #45.  This changes the API.  The old event
callback
scheme is removed (it was pretty horrible actually), and I’m exposing
an
“aio” framework.

The way aio’s work is that you allocate one (it’s like a handle) with
a
completion callback and a user supplied argument for the callback.

Then you can submit operations and get notified when they are
complete
later.  You can also wait on them to be complete.

E.g:

```
nng_aio *a;
void mycallback(void *);
void *myarg;

nng_aio_alloc(&a, mycallback, myarg);
nng_aio_set_timeout (a, 100);
nng_aio_set_message (a, msg);

What are the message setting/getting semantics? "Ownership" is
transferred into the operation? Or the message curator(s) retain
ownership during the operation?

nng_send_aio(s, a);

… asynchronously the message is sent, and the mycallback is executed.
… it can read the aio result via nng_aio_result (a);

Operations can also be canceled with nng_aio_cancel().

You can then do nng_aio_wait(a).

The details are for now in the nng.h header file.

Note that this is largely the same stuff I’m using *internally* in
nng.
I
figured that it was so useful to me that folks building other kinds
of
async
apps could use it.  For example, this could be used to integrate into
an
event loop or drive state machine transitions, etc.

Anyway, not sure how many of you might be poking at nng these days,
but
this
was the major API change that I wanted to get through before
declaring a
broader beta release.  I’d appreciate folks bang away at this.

I’m still going to try to get websocket and TLS support knocked out
before
*formal* beta. Oh, and I need to write a lot more docs. :-)

Enjoy!

 - Garrett






Other related posts: