Basically -- reverse the normal "server" paradigm, and use an XREP  
socket on the device side, then have each server send a single message  
when it wakes up on its REQ socket.  This message identifies the  
server to the device side by UUID.  The server will be back to  
alternative recv-send cycles (just offset by one).

[[ clients ]] -- [REQ] = [XREP] --- DEVICE --- [XREP] = [REQ] --  
[[ servers ]]

The server UUIDs go into a "server free list", which can then be used  
to schedule clients.

When you read the client packet stream (UUID,NULLPACKET,data) to  
service a client, you need to keep the <serverUUID, clientUUID> pair  
in a(n unordered) map, so when the server finishes the client response  
can be transmitted, and the server pushed back to the freelist.

If there is no server when you receive a client request  
( server_free_list.empty() ) you can then respond back immediately  
with a failure message.

Alternatively, if you don't want to dequeue requests until a server is  
free, just poll ONLY the server list while server_free_list.empty().

If you need to handle a timeout scenario, either pull the client  
requests out of the XREP, put them into unrolled lists of zmq_msg_t or  
equivalent, and build a small timer chain to return an error and kill  
a set (or unordered_map) with the requests.

(The zmq_reactor library should help a bit here, that's what I'm using  
for all this...)

Best,

Matt

On Aug 10, 2010, at 12:46 PM, Ilja Golshtein wrote:

> Martin, Matt,
>
> thank you very much for clarification
> and for speedy answering.
>
> To be honest I don't fill why spurious wakeups are unavoidable in  
> 0mq ... though it doesn't matter.
>
> Here is a mockup of client application
>
> ==
>    //  One I/O thread in the thread pool will do.
>    zmq::context_t ctx (1);
>    std::auto_ptr<zmq::socket_t> sp;
>    sp.reset(new zmq::socket_t(ctx, ZMQ_REQ/*ZMQ_XREQ*/));
>
>    //  Connect to the server.
>    sp->connect ("tcp://localhost:23001");
>
>    for (int i = 0; i != 20; i++)
>    {
>      zmq::message_t request (10);
>      strcpy((char*)request.data (), "AAAAAAAAA");
>      sp->send (request);
>      std::cout << "sent" << std::endl;
>
>
>      zmq_pollitem_t items[1];
>      items[0].socket = *sp.get();;
>      items[0].events = ZMQ_POLLIN;
>
>      struct timespec tp1;
>      ::clock_gettime(CLOCK_MONOTONIC, &tp1);
>      for (;;)
>      {
>        int poll_ret = zmq::poll(items, 1, 3000000);
>        if (items[0].revents == ZMQ_POLLIN)
>        {
>          assert(poll_ret > 0);
>
>          //  Get the reply.
>          zmq::message_t reply;
>          sp->recv(&reply);
>          std::cout << (char*)reply.data() << std::endl;
>          break;
>        }
>        else
>        {
>          std::cout << "no event fired" <<
>            "poll_ret=" << poll_ret << std::endl;
>          struct timespec tp2;
>          ::clock_gettime(CLOCK_MONOTONIC, &tp2);
>          if (tp2.tv_sec - tp1.tv_sec < 3)
>          {
>            continue;
>          }
>          else
>          {
>            std::cout << "reconnecting - message lost" << std::endl;
>            sp.reset(new zmq::socket_t(ctx, ZMQ_REQ));
>            sp->connect ("tcp://localhost:23001");
>            break;
>          }
>        }
>      }
>    }
> ==
>
> The goals are
> 1. Don't got stuck if response is lost
> 2. Not block if server unavailable.
>
> The only reason of recreating socket is REQ/REP paradigm (perhaps  
> XREQ/XREP are more suitable).
>
> Suggestions are appreciated.
>
> Thanks.
>
>
> 10.08.2010, 18:07, "Matt Weinstein" <matt_weinst...@yahoo.com>:
>> This is the same problem as pthread condition variables have, e.g.:
>>
>> http://www.justsoftwaresolutions.co.uk/threading/condition-variable-spurious-wakes.html
>>
>> Just think of the revents as condition variables to check...
>>
>> Does someone want to write a quick wrapper ?
>>
>> PS I recommend CLOCK_MONOTONIC, but it may not be available, and
>> requires -lrt ...
>>
> --
> Best regards
> Ilja Golshtein
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev@lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev

_______________________________________________
zeromq-dev mailing list
zeromq-dev@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to