3

I am trying to implement a Producer-Consumer pattern that uses multi-agents as workers instead of multi-threads.

As I understand, a typical multi-threaded implementation uses a BlockingQueue where one Producer thread puts information on the Queue and have multiple Consumer threads pull the data and execute some processing functions.

So following the same logic, my design will use a Producer agent that generates data and sends it to multiple Consumer Agents. At first guess, I have thought I should use a shared BlockingQueue between the Consumer agents and have the agents access the queue and retrieve the data. But I don't know if this is easy to do because I don't think agents have any shared memory and it is way more simple to directly send the information to the Consumer agents as ACL Messages.

This is important to consider because my multi-agent design will process a lot of data. So my question is, in Jade, what happens if I send to many ACL messages to a single agent? will the agent ignore the other messages?

This post has an answer that suggests "..Within the JADE framework, Agents feature an 'Inbox' for ACLMessages, basically a BlockingQueue Object that contains a list of recieved messages. the agent is able to observe its own list and treat them as its lifecycle proceeds. Containers do not feature this ability...". Is that statement correct? If this is true, then the other messages are just waiting on the queue and it will be ideal for my design to send information directly to the Consumer Agents, but I didn't see any BlockingQueues on the ACLMessage class.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • look at jade.core.Agent#receive(). You will see MessageQueue and synchronized that blocks the queue. You should undestand if count of your messages is more than queue's maxsize (MessageQueue.getMaxSize), your first messages will be removed (InternalMessageQueue.addLast) – nikelyn Jun 25 '18 at 09:04
  • I understand, I have tried implementing the design and I noticed the agents gets progressively slow as the queue gets filled with other ACL Messages. I am guessing it's something related to the size or the length of the message queue. How can I solve this problem ? Consumer agents are slow because they process the ACLMessages while others are received. –  Jul 03 '18 at 15:06
  • Does consumer agent process only one message at a time? I mean at one iteration in cycle behavior...Maybe you should create more consumer agents? – nikelyn Jul 03 '18 at 17:31
  • Thank you for your answer. The `producer` agent reads data from file and sends each agent a single line (The first line to the first agent, second to second... etc.). Each `consumer` agent process the message as soon as it's received. I believe the `consumer` agents lag because they can't up with with the message queue filled by `producer` agent. Is that clear enough? So my code's problem is that it sends a lot of messages to multiple agents, I don't know how to solve/optimize this. –  Jul 03 '18 at 20:01
  • have you tried to process several messages at once in consumer agent? something like this: int size = myAgent.getCurQueueSize(); if(size == 0){ block(); return; } for(int i = 0; i < size; i++){ ACLMessage message = myAgent.receive(); // your process code } – nikelyn Jul 07 '18 at 19:31

1 Answers1

1

Yes, messages will be in queue and agent will not ignore them.

ACLMessage is just a message object, that is sent between agents. Each agents has its own message queue (jade.core.MessageQueue) and several methods for handling communication.

If you check Agent class documentation, you can find methods like

  • receive() - nonblocking receive, returns first message in queue or null if queue is empty
  • receive(MessageTemplate pattern) - behaves like the the previous one, but you can also specify pattern for message, like for example specific sender AID, conversation ID, also combinations.
  • blockingReceive() - blocking receive, blocks agent until message appears in queue
  • blockingReceive(MessageTemplate pattern) - blocking receive, with pattern

and also there are methods for blocking receive, where you can set the timeout.

It's also important to mention, that if you define your agent logic in Behaviour class, you can also just block only behaviour, instead of blocking entire agent.

ACLMessage msg = agent.receive();    
if (msg != null) {
    // your logic
} else {
    block();            
}

The difference, is that block() method inside behaviour just marks your behaviour as blocked and removes it from agent's active behaviour pool (it added back to active pool, when message is received or behaviour is restared by restart() method) allowing to execute other agent's behaviours, and blockingReceive() blocks entirely your agent and all his behaviours until he receives message.

  • Thank you for your answer. I am using a `CyclicBehaviour` class to handle the received ACL messages as it is recommended. It is true that ACL messages are blocked in the queue and are not ignored, but the agents gets progressively slow as the queue gets filled with other ACL Messages. I am guessing it's something related to the size or the length of the message queue. How can I solve this problem ? `Consumer` agents are slow because they process the ACLMessages while others are received. –  Jun 29 '18 at 12:31