Skip to content

Herd Agent

BorjaFG edited this page Mar 15, 2019 · 15 revisions

Herd Agent logo

The Herd Agent is a Windows service/Linux daemon that executes jobs sent from a client (i.e, Badger) and, once the job is finished, returns the results to the client.

Host / Client design

All the networking functionality is implemented in the Herd project. The classes used by the client of the service (Shepherd) and the host service (HerdAgent) both inherit from JobDispatcher, which implements methods to send jobs and receive the results back asynchronously. As in the rest of the project, messages in the protocol are based on XML.

Agent discovery

When a client wants to find out which agents can be used to run whatever jobs it wants to send, it sends a broadcast message via UDP (no broadcast can be done using TCP), and agents answer to the client sending information about their availability and some properties of the host machine: number of processors, available RAM memory, version of the service, etc... For simplicity, the agents can only receive as many tasks as the processor count -1. Once they all end, results are sent to the client and the agent will report that it is again available.

The agent listens to port JobDispatcher.m_discoveryPortHerd and, when a JobDispatcher.m_discoveryMessage message is received, the information of the local machine is gathered and sent to the client in HerdAgent.DiscoveryCallback().

Sending jobs to an agent

Once a client has a list of agents (which may be available or busy), it can send jobs to whichever agents it wants to use. The jobs are transmitted using an XML-based format via TCP using port JobDipatcher.m_comPortHerd. When a job request is received, the agent handles it in HerdAgent.CommunicationCallback()

A job consists of a list of input files (to avoid sending over the same file more than once), a list of output files that are to be returned to the client after execution, and a list of tasks (commands).

public class Job
{
  public string name;
  public List<Task> tasks;
  public List<string> inputFiles;  
  public List<string> outputFiles;
  public Dictionary<string, string> renameRules;
}

Each job has a name, a list of input files (which are sent with the job request), and a list of output files which are expected to be output by the tasks and returned to the client. If an input file should be copied to a different location in the herd agent's folder structure, rename rules can be added to renameRules, where the key is the path to the input file to be renamed, and the value is the name to be given in the host machine (herd agent). Each of the tasks is run on a separate process.

public class Task
{ 
  public string exe;
  public string arguments;
  public string pipe;
  public string name;
}

The path to the exe file to be executed is set in exe, its arguments in arguments, the name of the task in name, and the name of the pipe in pipe. This pipe can be used by the executable file to send updates on the progress to the local HerdAgent service. Because at the time we programmed the lowest layer of the agent, it wasn't clear whether pipes over TCP were supported, we chose to make the executable messages to the local herd agent, which then sends them to the client via TCP. The progress of all the tasks is sent via the same port with a different XML tag. All the output files from all the tasks are sent in the same message, after all tasks have finished.

The HerdAgent Windows service stores temporal copies of the input/output files in the [HerdAgentInstallDir]/temp directory and, on startup, it deletes all the files/directories in this temporal directory that are at least 2 weeks old.

Clone this wiki locally