All Downloads are FREE. Search and download functionalities are using the official Maven repository.

goal.core.agent.AgentRegistry Maven / Gradle / Ivy

The newest version!
package goal.core.agent;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ImmutableSet;

import goal.tools.errorhandling.Warning;
import goal.tools.errorhandling.exceptions.GOALLaunchFailureException;
import languageTools.program.agent.AgentId;
import languageTools.program.agent.msg.Message;

/**
 * A registry is a map of agent ids to agents. It is used to keep track of all
 * the agents in a MAS, whether locally or remotely. Agents that run on the same
 * host as the registry are stored in the map by means of their agent id. If an
 * agent runs remotely, the id of that agent is mapped to the remote registry
 * that runs on the remote machine and is made available to the local host.
 * 

* A registry itself is a (special) agent that only maintains a message queue. A * registry can receive messages itself in its message queue but that only * happens if another registry has sent it a message. A registry sends a message * to another registry if it cannot deliver the message itself locally. In order * to be able to deliver messages remotely, a registry needs a messaging * capability to deliver the message to a remote machine. *

* * TODO: (stuff only needed for remote messaging) - The idea is that an agent no * longer has a messaging capability, but that a registry has one instead. The * messaging capability still needs to be removed from the Agent class and added * to the AgentRegistry class. - make available remote registries to be able to * store remote agent ids (the remote registry is needed to send a message to * the remove agent). - add the registry to the pool of agents and execute it * once every while to handle messages that it has received from other (remote) * registries and that it should deliver locally. */ public class AgentRegistry extends Agent { /** * Map of the agents that exist in the MAS. */ private Map> agents = new HashMap<>(); /** * Map of channels and which agents are subscribed to them. */ private Map> channels = new HashMap<>(); /** * Creates a registry as a special agent with only messaging and logging * capabilities. * * @throws GOALLaunchFailureException */ @SuppressWarnings("unchecked") public AgentRegistry(LoggingCapabilities logger) throws GOALLaunchFailureException { super(new AgentId("registry"), new NoEnvironmentCapabilities(), logger, (CONTROLLER) new NOPController(), null, 0); } public AgentId getAgentid(String name) { AgentId id = new AgentId(name); int serial = 0; synchronized (this.agents) { while (this.agents.containsKey(id)) { id = new AgentId(name + "_" + serial++); } this.agents.put(id, null); // make reservation } return id; } /** * @param aid An agent id. * @return The agent with the given id, or {@code null} if no such agent has * registered. */ public Agent getAgent(AgentId aid) { synchronized (this.agents) { return this.agents.get(aid); } } /** * @return A set of registered agent ids. */ public Set getRegisteredAgents() { synchronized (this.agents) { return ImmutableSet.copyOf(this.agents.keySet()); } } /** * Registers an agent and adds it into the registry. * * @param agent An agent. */ public void register(Agent agent) { synchronized (this.agents) { this.agents.put(agent.getId(), agent); } } /** * Removes an agent from the registry ánd all channels. * * @param aid An agent id. */ public void unregister(AgentId aid) { synchronized (this.agents) { this.agents.remove(aid); } for (String channel : getAllChannels()) { unsubscribe(aid, channel); } } /** * Posts a message and inserts it into the mailbox of the agent(s) that should * receive it. Agent might be another registry. * * @param message A message. * @return {@link Warning} if something went wrong, or null if all OK. */ public Warning postMessage(Message message) { List succeeded = new LinkedList<>(); List failed = new LinkedList<>(); for (AgentId aid : message.getReceivers()) { Agent agent = getAgent(aid); if (agent != null) { agent.receiveMessage(message); succeeded.add(aid); } else { failed.add(aid); } } if (!failed.isEmpty()) { return new Warning("failed to deliver the message '" + message.getContent() + "' to " + failed + "."); } else if (succeeded.isEmpty()) { return new Warning("there were no receivers for the message '" + message.getContent() + "'."); } return null; } // TODO: DOCUMENT THE BELOW FUNCTIONS /** * @return A set of registered agent ids. */ public Set getAllChannels() { synchronized (this.channels) { return ImmutableSet.copyOf(this.channels.keySet()); } } public boolean subscribe(AgentId aid, String channel) { synchronized (this.channels) { Set current = this.channels.get(channel); if (current == null) { Set newchannel = new HashSet<>(); newchannel.add(aid); this.channels.put(channel, newchannel); return true; } else { return current.add(aid); } } } public boolean unsubscribe(AgentId aid, String channel) { synchronized (this.channels) { Set current = this.channels.get(channel); boolean removed = current != null && current.remove(aid); if (removed && current.isEmpty()) { this.channels.remove(channel); } return removed; } } public boolean isChannel(String channel) { synchronized (this.channels) { return this.channels.containsKey(channel); } } public Set getSubscribers(String channel) { synchronized (this.channels) { Set current = this.channels.get(channel); return (current == null) ? new HashSet<>(0) : ImmutableSet.copyOf(current); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy