how to design a structure with ZeroMQ for this case

Here is my plan:
I have many agents and one agent manager.
If an agent runs, it will connect the agent manager saying: I'm agent.
The agent manager can control all of running agents. For example, the agent manager can say: agent1, plz do something. Here is an example:

*****************                       *********
* agent manager * <-----I'm agent1----- * Agent *
*               * ---------OK---------> *       *
*               *                       *       *
*               * ---calculate 1+1----> *       *
*               * <-------It's 2------- *       *
*               * -------go sleep-----> *       *
*               * <--OK, I'm sleeping-- *       *
*               * ------wake up-------> *       *
*               * <---------OK--------- *       *
*               * ---calculate 1+2----> *       *
*               * <-------It's 3------- *       * 
*****************          ...          *********

I'm considering using the REQ/REP, but it seems it won't work. Because things happen like this: request --- reply --- reply --- request --- reply --- request...

Besides, we may have more than one agent. It means that the agent manager can control many agents at the same time. So I want to use multi-threading, but my boss doesn't agree. He wants to use mono-threading for now. So I think I should use "non-blocking" mode.

So how could I design a 0MQ pattern for this case with non-blocking?


Use Dealer(Agent)/Router(Agent Manager). They'll be a drop in replacement for REQ/REP, as they are more or less identical, just with an unstructured communication pattern. Your Agent Manager will receive the ID of each Agent as part of the communication, in the first frame of the message. It will need to keep track of these IDs so that it can initiate communication back to them. There are examples for how this works in the ZMQ guide which you should definitely read if you have not. Specifically, take a look at this section to see how this works. Quick diagram:

DEALER1-setID('agent1')                        ROUTER-bind()
DEALER1-connect()-------------------------------->  *
DEALER1-send("I'm agent1")-------------->  ROUTER-recv(['agent1', "I'm agent1"])
DEALER1-recv('OK')  <----------------------ROUTER-send(['agent1', 'OK'])



DEALER2-setID('agent2')
DEALER2-connect()-------------------------------->  *
DEALER2-send("I'm agent2")-------------->  ROUTER-recv(['agent2', "I'm agent2"])
DEALER2-recv('OK')  <----------------------ROUTER-send(['agent2', 'OK'])


DEALER1-recv('calc 1+1')  <----------------ROUTER-send(['agent1', 'calc 1+1'])
DEALER2-recv('calc 1+2')  <----------------ROUTER-send(['agent2', 'calc 1+2'])

DEALER1-send("It's 2")------------------>  ROUTER-recv(['agent1', "It's 2"])
DEALER1-recv('go sleep')  <----------------ROUTER-send(['agent1', 'go sleep'])
DEALER2-send("It's 3")------------------>  ROUTER-recv(['agent2', "It's 3"])
DEALER1-send("OK, I'm sleeping")-------->  ROUTER-recv(['agent1', "OK, I'm sleeping"])

... and so on. I intentionally interleaved the message responses just to demonstrate how it might work with more complicated jobs that take differing amounts of time. The way the ID gets received by ROUTER in a way you can access, and sent by ROUTER but stripped off by DEALER is inherent in how these socket types operate. You just need to track these IDs, know which ones are being used and only send to ones that don't yet have a job until you receive a response.

链接地址: http://www.djcxy.com/p/18380.html

上一篇: 带有REQ和REP套接字的C ++ ZeroMQ单一应用程序

下一篇: 如何在这种情况下使用ZeroMQ设计结构