Problem

You want your task to run only on a specified list of machines.

Solution

Use task preconditions to control how a task is assigned. Many options can be controlled, including agent hostname, number of available cores, and hard disk space.

You can add task preconditions to the job by using the getTaskPreconditions() method. The CommonResources enumeration contains resource types that you will use most often.

Java  Copy imageCopy
package stkscalabilitysdk.howto;


import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

import agi.parallel.client.ClusterJobScheduler;
import agi.parallel.client.IEnforceTaskPrecondition;
import agi.parallel.client.IGetAgentInfo;
import agi.parallel.client.IJobScheduler;
import agi.parallel.client.Job;
import agi.parallel.infrastructure.AgentSnapshot;
import agi.parallel.infrastructure.CommonResources;
import agi.parallel.infrastructure.Operator;
import agi.parallel.infrastructure.Task;

public class TaskPrecondition {
    public static void main(String[] args) {
        IJobScheduler scheduler = new ClusterJobScheduler("localhost");
        try {
            scheduler.connect();

            // Check if this feature is supported by querying for the IEnforceTaskPrecondition interface.
            IEnforceTaskPrecondition preconditionCapable = (IEnforceTaskPrecondition) scheduler;
            if (preconditionCapable != null) {
                List<AgentSnapshot> agents = ((IGetAgentInfo) preconditionCapable).getAgentInfo();
                String agentMachineName = agents.get(0).getMachineName();
                Job job = scheduler.createJob();

                // Restrict the task to be run only on the first agent machine.
                job.getTaskPreconditions().add(CommonResources.HOSTNAME, Operator.MEMBER_OF, new String[] {
                    agentMachineName
                });

                // Restrict the task to be run on machines that have at least 1 empty host slot.
                job.getTaskPreconditions().add(CommonResources.AVAILABLE_CORES, Operator.GREATER_THAN, 0);
                job.addTask(new RestrictedTask());
                job.submit();
                job.waitUntilDone();
                System.out.println(job.getTasks().get(0).getResult());
            } else {
                System.out.println("This job scheduler does not support task preconditions.");
            }
        } finally {
            scheduler.dispose();
        }

        /*
         * The output of the application should resemble:
         * Hello from MyComputerName
         */
    }

    public static class RestrictedTask extends Task {
        @Override
        public void execute() {
            try {
                this.setResult("Hello from " + InetAddress.getLocalHost().getHostName());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
}

Discussion

It is a common pattern to execute tasks only on a restricted set of machines. Examples include:

  • Forcing the task to be executed only on a predefined set of machines.
  • Reserving system resources on a machine; for example: only use 2 cores of a 4 core machine.
  • Executing a task only if it has a specific resource, for example: only use machines that have STK installed.
  • Executing a task only if it has enough memory or hard disk space.

A helpful method to use in combination with getTaskPreconditions() is getAgentInfo(). GetAgentInfo will return a list of agents, which can be used to determine currently available resources before tasks are submitted.

See Also