Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
If you want to run a job multiple times (you cannot rerun a finished job or move it back to the configuring state) or if you want to create variations of a job, call the IScheduler::CloneJob method to create a job that is a copy of the specified job.
The CloneJob method copies all the tasks (includes the instances for parametric tasks) and a subset of the job and task property values. For a list of the properties that the method copies, see the Remarks section for the CloneJob method.
You can clone a job that is in any state; however, only the owner of the job can clone the job.
If a job fails, you can either clone the job (if you want to save its state) or you can call the IScheduler::ConfigureJob method to move the job back to the configuring state to fix the cause of the error.
The following C# example shows how to clone a job, change the properties on the existing tasks, add a new task, and submit the new job.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Hpc.Scheduler;
using Microsoft.Hpc.Scheduler.Properties;
namespace CloneJob
{
class Program
{
private static IScheduler m_scheduler = null;
static void Main(string[] args)
{
ISchedulerJob clonedJob = null;
int jobId = 0;
try
{
m_scheduler = new Scheduler();
m_scheduler.Connect("localhost");
jobId = CreateJob();
PrintTasks(m_scheduler.OpenJob(jobId));
clonedJob = m_scheduler.CloneJob(jobId);
PrintTasks(m_scheduler.OpenJob(clonedJob.Id));
UpdateClonedJob(clonedJob);
PrintTasks(m_scheduler.OpenJob(clonedJob.Id));
m_scheduler.SubmitJob(clonedJob, @"<USERNAMEGOESHERE>", null);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Creates a job, adds a task and a parametric task to the job, and
// then submits the job.
private static int CreateJob()
{
ISchedulerJob job = null;
ISchedulerTask task = null;
job = m_scheduler.CreateJob();
// Create a parametric task
task = job.CreateTask();
task.CommandLine = @"echo *";
task.IsParametric = true;
task.StartValue = 1;
task.EndValue = 5;
task.IncrementValue = 1;
job.AddTask(task);
// Create a task
task = job.CreateTask();
task.CommandLine = @"ping <COMPUTERNAMEGOESHERE>";
job.AddTask(task);
m_scheduler.SubmitJob(job, @"<USERNAMEGOESHERE>", null);
return job.Id;
}
// Print the tasks IDs of the tasks in the job. Include StdOut
// to show the update to the tasks.
private static void PrintTasks(ISchedulerJob job)
{
Console.WriteLine("Tasks for job " + job.Id);
foreach (ISchedulerTask task in job.GetTaskList(null, null, true))
{
Console.WriteLine("id({0}), instance({1}), job({2})",
task.TaskId.JobTaskId, task.TaskId.InstanceId, task.TaskId.ParentJobId);
Console.WriteLine("\tcommand: " + task.CommandLine);
Console.WriteLine("\tstdout: " + task.StdOutFilePath);
}
Console.WriteLine();
}
// Update the cloned job. Add StdOut path to capture output from tasks.
// Add a new task to the job.
private static void UpdateClonedJob(ISchedulerJob job)
{
ISchedulerTask task = null;
ITaskId taskId = null;
// Get the parametric task. Update the start value and
// set the stdout path.
taskId = m_scheduler.CreateTaskId(1);
task = job.OpenTask((TaskId)taskId);
task.StartValue = 3;
task.StdOutFilePath = @"<PATHGOESHERE>\echo_inst*.txt";
task.Commit();
// Add a new task to the job.
task = job.CreateTask();
task.CommandLine = @"echo 'new task'";
task.StdOutFilePath = @"<PATHGOESHERE>\new.txt";
job.AddTask(task);
}
}
}
The following C++ example shows how to clone a job, change the properties on the existing tasks, add a new task, and submit the new job.
#include <windows.h>
#include <stdio.h>
// The Microsoft.Hpc.Scheduler.tlb and Microsoft.Hpc.Scheduler.Properties.tlb type
// libraries are included in the Microsoft HPC Pack 2008 SDK. The type libraries are
// located in the "Microsoft HPC Pack 2008 SDK\Lib\i386" or \amd64 folder. Include the rename
// attributes to avoid name collisions.
#import <Microsoft.Hpc.Scheduler.tlb> named_guids no_namespace raw_interfaces_only \
rename("SetEnvironmentVariable","SetHpcEnvironmentVariable") \
rename("AddJob", "AddHpcJob")
#import <Microsoft.Hpc.Scheduler.Properties.tlb> named_guids no_namespace raw_interfaces_only
IScheduler* g_pScheduler = NULL;
long CreateJob(void);
void PrintTasks(int JobId);
void UpdateClonedJob(int JobId);
void wmain(int argc, WCHAR *argv[])
{
HRESULT hr = S_OK;
ISchedulerJob* pClonedJob = NULL;
long JobId = 0;
long ClonedJobId = 0;
// Use the apartment-threaded model to ensure the code is thread safe.
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Get an instance of the Scheduler object.
hr = CoCreateInstance( __uuidof(Scheduler), // CLSID_Scheduler,
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IScheduler), // IID_IScheduler,
reinterpret_cast<void **> (&g_pScheduler) );
if (FAILED(hr))
{
wprintf(L"CoCreateInstance(IScheduler) failed with 0x%x.\n", hr);
goto cleanup;
}
hr = g_pScheduler->Connect(_bstr_t(L"localhost"));
if (FAILED(hr))
{
wprintf(L"Unable to connect to localhost. Failed with 0x%x.\n", hr);
goto cleanup;
}
wprintf(L"Connected to localhost\n");
JobId = CreateJob();
if (JobId)
{
PrintTasks(JobId);
hr = g_pScheduler->CloneJob(JobId, &pClonedJob);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->CloneJob failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pClonedJob->get_Id(&ClonedJobId);
PrintTasks(ClonedJobId);
UpdateClonedJob(ClonedJobId);
PrintTasks(ClonedJobId);
hr = g_pScheduler->SubmitJobById(ClonedJobId, _bstr_t(L"<USERNAMEGOESHERE>"), NULL);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->SubmitJobById failed with 0x%x.\n", hr);
goto cleanup;
}
}
cleanup:
// Before exiting, release your instance of IScheduler.
if (g_pScheduler)
g_pScheduler->Release();
if (pClonedJob)
pClonedJob->Release();
CoUninitialize();
}
long CreateJob(void)
{
HRESULT hr = S_OK;
ISchedulerJob* pJob = NULL;
ISchedulerTask* pTask = NULL;
long JobId = 0;
hr = g_pScheduler->CreateJob(&pJob);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->CreateJob failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->CreateTask(&pTask);
if (FAILED(hr))
{
wprintf(L"pJob->CreateTask failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_CommandLine(_bstr_t(L"echo *"));
if (FAILED(hr))
{
wprintf(L"pTask->put_CommandLine failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_IsParametric(VARIANT_TRUE);
hr = pTask->put_StartValue(1);
hr = pTask->put_EndValue(5);
hr = pTask->put_IncrementValue(1);
hr = pJob->AddTask(pTask);
if (FAILED(hr))
{
wprintf(L"pTask->AddTask failed with 0x%x.\n", hr);
goto cleanup;
}
pTask->Release();
pTask = NULL;
hr = pJob->CreateTask(&pTask);
if (FAILED(hr))
{
wprintf(L"pJob->CreateTask failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_CommandLine(_bstr_t(L"ping <COMPUTERNAMEGOESHERE>"));
if (FAILED(hr))
{
wprintf(L"pTask->put_CommandLine failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->AddTask(pTask);
if (FAILED(hr))
{
wprintf(L"pJob->AddTask failed with 0x%x.\n", hr);
goto cleanup;
}
hr = g_pScheduler->SubmitJob(pJob, _bstr_t("<USERNAMEGOESHERE>"), NULL);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->SubmitJob failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->get_Id(&JobId);
cleanup:
if (pJob)
pJob->Release();
if (pTask)
pTask->Release();
return JobId;
}
void PrintTasks(int JobId)
{
HRESULT hr = S_OK;
ISchedulerJob* pJob = NULL;
ISchedulerTask* pTask = NULL;
ISchedulerCollection* pCollection = NULL;
ITaskId* pTaskId = NULL;
_variant_t var;
long JobTaskId = 0;
long InstanceId = 0;
long Count = 0;
_bstr_t bstrCommand;
_bstr_t bstrStdOut;
wprintf(L"Tasks for job %d\n", JobId);
hr = g_pScheduler->OpenJob(JobId, &pJob);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->OpenJob failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->GetTaskList(NULL, NULL, VARIANT_TRUE, &pCollection);
if (FAILED(hr))
{
wprintf(L"pJob->GetTaskList failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pCollection->get_Count(&Count);
for (long i = 0; i < Count; i++)
{
hr = pCollection->get_Item(i, &var);
if (FAILED(hr))
{
wprintf(L"pCollection->get_Item failed with 0x%x.\n", hr);
goto cleanup;
}
hr = var.pdispVal->QueryInterface(IID_ISchedulerTask, reinterpret_cast<void**>(&pTask));
hr = pTask->get_TaskId(&pTaskId);
if (FAILED(hr))
{
wprintf(L"pTask->get_TaskId failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTaskId->get_JobTaskId(&JobTaskId);
hr = pTaskId->get_InstanceId(&InstanceId);
wprintf(L"id(%d), instance(%d), job(%d)\n", JobTaskId, InstanceId, JobId);
hr = pTask->get_CommandLine(&(bstrCommand.GetBSTR()));
if (FAILED(hr))
{
wprintf(L"pTask->get_CommandLine failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->get_StdOutFilePath(&(bstrStdOut.GetBSTR()));
if (FAILED(hr))
{
wprintf(L"pTask->get_StdOutFilePath failed with 0x%x.\n", hr);
goto cleanup;
}
wprintf(L"\tCommand: %s\n\tStdOut: %s\n", bstrCommand.GetBSTR(), bstrStdOut.GetBSTR());
pTask->Release();
pTask = NULL;
pTaskId->Release();
pTaskId = NULL;
}
wprintf(L"\n");
cleanup:
if (pJob)
pJob->Release();
if (pTask)
pTask->Release();
if (pTaskId)
pTaskId->Release();
if (pCollection)
pCollection->Release();
}
void UpdateClonedJob(int JobId)
{
HRESULT hr = S_OK;
ISchedulerJob* pJob = NULL;
ISchedulerTask* pTask = NULL;
ISchedulerCollection* pCollection = NULL;
ITaskId* pTaskId = NULL;
hr = g_pScheduler->OpenJob(JobId, &pJob);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->OpenJob failed with 0x%x.\n", hr);
goto cleanup;
}
// Get the parametric task. Change the start
// value and set the stdout path.
hr = g_pScheduler->CreateTaskId(1, &pTaskId);
if (FAILED(hr))
{
wprintf(L"g_pScheduler->CreateTaskId failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->OpenTask(pTaskId, &pTask);
if (FAILED(hr))
{
wprintf(L"pJob->OpenTask failed with 0x%x.\n", hr);
goto cleanup;
}
pTaskId->Release();
pTaskId = NULL;
hr = pTask->put_StartValue(3);
if (FAILED(hr))
{
wprintf(L"pTask->put_StartValue failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_StdOutFilePath(_bstr_t(L"<FULLPATHGOESHERE>\\echo_inst*.txt"));
if (FAILED(hr))
{
wprintf(L"pTask->put_StdOutFilePath failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->Commit();
if (FAILED(hr))
{
wprintf(L"pTask->Commit failed with 0x%x.\n", hr);
goto cleanup;
}
pTask->Release();
pTask = NULL;
// Add a new task to the job.
hr = pJob->CreateTask(&pTask);
if (FAILED(hr))
{
wprintf(L"pJob->CreateTask failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_CommandLine(_bstr_t(L"echo \"new task\""));
if (FAILED(hr))
{
wprintf(L"pTask->put_CommandLine failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pTask->put_StdOutFilePath(_bstr_t(L"<FULLPATHGOESHERE>\\new.txt"));
if (FAILED(hr))
{
wprintf(L"pTask->put_StdOutFilePath failed with 0x%x.\n", hr);
goto cleanup;
}
hr = pJob->AddTask(pTask);
if (FAILED(hr))
{
wprintf(L"pJob->AddTask failed with 0x%x.\n", hr);
goto cleanup;
}
cleanup:
if (pJob)
pJob->Release();
if (pTask)
pTask->Release();
if (pTaskId)
pTaskId->Release();
}