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

  • From: Martin Sustrik <sustrik@xxxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Mon, 18 Nov 2013 20:08:08 +0100

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

On 18/11/13 17:00, Schmurfy wrote:
> I really like the idea of being able to pass a void pointer, as for
> freeing its associated memory I not sure what would be the best
> way, for me the way is usually work with zmq/libxs is:
> 
> - create the zmq/libxssockets - poll/select all the unix selectors 
> - for each socket with data avaible: - read data - find associated
> thread or whatever is waiting for it and wake it up

Yes, the void* would point to that 'whatever'.

Some APIs (signals, epoll) opt for a more versatile approach though.
Instead of void* they use an union, like this:

typedef union {
    void *ptr;
    int *i;
    uint32_t i32;
} request_id_t;

> in this scenario the void* pointer may be directly the thread id
> which would not require any cleanup, otherwise if memory needs to
> be freed maybe a way to get the pointer knowing the socket and
> request id would be enough, something like this:
> 
> nn_get_request_data_ptr(int s, int req_id)

Now, the question of timeouts and/or cancellation of requests is
orthogonal to the request-id type.

> if there is a way to have a timeout trigger the exception state of
> the socket the loop should work too for this case.
> 
> 
> Here is what I currently do with a custom tcp protocol we use at
> work: - we have two types of messages: req and ack - all requests
> have an id - the server keeps track of requests which are being
> executed and send a pending ack to the client if the request is
> sent again - if a response is not received after X seconds the
> request is sent again, after Y retries without ack (pending is ok)
> the request is timed out and an error is raised to the caller
> 
> That's what we use with only one server serving the requests. I
> can't say that it's the best protocol in the world but it serves us
> well, I did some tests with zeromq (with XREQ/XREP obviously) and I
> hope to one day use nanomsg :p

Yes. The algorithm is almost the same in nanomsg. Except that there's
no ack. The reply itself serves as an ack.

The only thing missing AFAICS is keeping multiple parallel request
inside of REQ socket.

> I just added this as an example but I don't expect nanomsg to ever 
> implement everything in this list, the real question is what
> nanomsg REQ/REP could do to help implementing async patterns and
> still give enough liberty the the user to implement what he needs. 
> The other sockets types are pretty useful as is and they are the
> reason I got interested in zmq in the first place but I honestly
> never found a way to use REQ/REP as is, too many flaws at least in
> zmq.

Ok. Let me give an example:

// Open the connection to server.
s = nn_socket (AF_SP, NN_REQ);
nn_connect (s, "tcp://myserver:5555");

// Send first request. Associate it with dummy request context (simple
int).
const int first = 1;
nn_req_send (s, &first, "ABC", 3, 0);

//  Second request. Give it a different dummy context.
const int second = 2;
nn_req_send (s, &second, "DEF", 3, 0);

//  Wait for a reply.
int *context;
char reply [32];
nn_req_recv (s, &context, buf, sizeof (buf), 0);

//  Check which reply was received.
if (context == &first)
    printf ("Reply for first request was received.");
if (context == &second)
    printf ("Reply for second request was received.");

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

iQEcBAEBAgAGBQJSimWYAAoJENTpVjxCNN9Y1JUIAIE7XEWQ4nYox3ZqbcbkclMk
qdpk17Y/SEc72BIer6m4yYSbED191+1QwUCpf2zJ/Q//GGv4S6hxtZQEoXAPQlI2
1jix3mvjNkBjCGtuaB0N71vDFjCv4NNaDhI8Voh8c0UizBDAM0iSqtgPHLXauET3
fI0ETGPdxqMujmbhslrVCjgsa1Pe6oxahvpvPFkzGyWY56e3eLV8G2GccL8WiKTV
8rKiV7qN1xOeJY9vottgoFQVUGwmM0de8kc/E3m1K2ETKYdJqdzV+cvgFqoKGf2t
MIs07psCFyXlh4tQDsUUOPnqUFE39njLokpZUhyEC9O9Yjg9FnkAaYMxSkvVkf0=
=lLE4
-----END PGP SIGNATURE-----

Other related posts: