[nanomsg] Re: Asynchronous (raw) sockets in nanomsg

  • From: Martin Sustrik <sustrik@xxxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Sat, 16 Nov 2013 09:14:10 +0100

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Paul,

> I'm trying to make integration tests for nanomsg. The fact is that 
> most reasonable integration tests need many simultaneous requests,
> so I need to use raw sockets and reimplement the whole
> request-reply state machine for the task. Same problem has been
> solved in nanoconfig.

I suppose the problem is standard req/rep is the REQ socket can have
only one request at flight at any given moment, right?

The important point there is that that is only the implementation
limitation, not the protocol limitation. It should be relatively easy
to write a REQ implementation that would be able to support multiple
simultaneous requests. The only real problem is to make a nice API for
that.

> The outcome is that request-reply state machine will be
> reimplemented in many different frameworks and applications,
> probably with different characteristics. Here is a short summary of
> complexities for every implementation:
> 
> 1. Request id, random number generator: it's too attractive to use
> C random or something similar
> 
> 2. Request repeating: it's too easy to forget about it
> 
> 3. It's not possible to repeat request on reconnect (github issues
> #86, #87)
> 
> 4. recv() cuts request id, if its first in message (it's a bug
> that should probably be solved with recvmsg, but anyway), so you
> need to add additional useless pipe id by application.
> 
> 5. Even for simple tasks like "send 10 requests, receive 10
> replies" you need a NN_RCVFD and some kind of poll/select

Good analysis.

> (BTW: I've implemented asynchronous requests multiple times using
> XREQ for zeromq multiple times, but zeromq has no issue with items
> 4,5 and items 1-3 are there for REQ sockets too).
> 
> There are many ways to fix the situation:
> 
> 1. Implement functionality on top of nanomsg, along with async
> main loop (aka czmq)
> 
> 2. Implement functionality in high level language bindings (each of
> them)
> 
> 3. Implement functionality in nanomsg itself: a) using
> sendmsg/recvmsg b) add AF_SP_ASYNC protocol family
> 
> Any preferences? Thoughts?

I would go for 3. Everyone does it anyway, so it can very well be part
of the core library.

As for a) and b) there's also a c) option: Adjust REQ to support
multiple parallel requests.

Once again, the real question here is the API. How to make the thing
easy and intuitive to use.

Some thoughts:

In the long run we'll need to separate topic from message body in
PUB/SUB protocol to allow encrypting the body while keeping topic
visible to routing algos. That would mean setting topic via ancillary
data (sendmsg) which is a pain in the ass. What can be done is adding
a new protocol-specific helper function nn_pub_send(s, topic, body);
that would do the ancillary data stuff behind the scenes. In the land
of traditional networking similar approach is used, e.g. for
sctp_send() function.

With the above in mind, we can similarly create new nn_req_send() and
nn_req_recv() functions to handle the annoying sendmsg/recvmsg,
request ID etc. stuff. For example:

    int nn_req_send(int s, int request_id, void *buf, size_t len, int
flags);
    int nn_req_recv(int s, int *request_id, void *bud, size_t len, int
flags);

Thoughts?
Martin



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEbBAEBAgAGBQJShylRAAoJENTpVjxCNN9YB60H+POt6ue040+1Y5UuVEuwGLF0
DkBmI2GSgPkPkDRn5Lqi60IeT9zh/P6OMA2wRqgipmw5BjqCfxoK/2pBL7j3fc+X
GBWWCSsuFW28WwhJq6QxjDk32ESxtNVIWvMZbvUNlC75MhEPEKAlXZfonqJwvjXI
vf3RE26POlcPi8fJqIMMxYOBFLeoXA6HQ/huoFITj3Orlif0j6PEyiirQd2uiCni
WhQfieXMqatSFpNtdD4HDo+YqksUg/q6fN4d5V/Dd+favp6OvsYAjy/3fPUCQfPO
Q335pD4235BCCqdoTD3bI8E/fG3SSL0tGrkZWi3kckK+bFSQtMQSNfU0cHaesQ==
=N3JK
-----END PGP SIGNATURE-----

Other related posts: