private async System.Threading.Tasks.Task <List <JobModel> > ListJobsAsync(int min, int max)
        {
            List <JobModel> results = new List <JobModel>();

            string uppperBound = string.Format("job-{0:D10}", max);
            string lowerBound  = string.Format("job-{0:D10}", min);

            // TODO: Need to use the detail level to limit amount of data we download from the server
            // TODO: and increase the performace of listing jobs in the UI
            //var detailLevel = new ODATADetailLevel() { SelectClause = "name,state,creationTime" };
            //if (string.IsNullOrEmpty(detailLevel.FilterClause))
            //{
            //    detailLevel.FilterClause = string.Empty;
            //}
            //detailLevel.FilterClause += string.Format("(jobName le '{0}' and jobName gt '{1}')", uppperBound, lowerBound);
            //IEnumerableAsyncExtended<ICloudJob> jobList = this.WorkItem.ListJobs(detailLevel);
            // END TODO

            IEnumerableAsyncExtended <ICloudJob> jobList         = this.WorkItem.ListJobs();
            IAsyncEnumerator <ICloudJob>         asyncEnumerator = jobList.GetAsyncEnumerator();

            while (await asyncEnumerator.MoveNextAsync())
            {
                results.Add(new JobModel(this, asyncEnumerator.Current));
            }
            return(results);
        }
Esempio n. 2
0
        /// <summary>
        /// Lists the Tasks matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for Tasks</param>
        /// <returns>The Tasks matching the specified filter options</returns>
        public IEnumerable <PSCloudTask> ListTasks(ListTaskOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if ((string.IsNullOrEmpty(options.WorkItemName) || string.IsNullOrEmpty(options.JobName)) && options.Job == null)
            {
                throw new ArgumentNullException(Resources.GBT_NoJob);
            }

            // Get the single Task matching the specified name
            if (!string.IsNullOrEmpty(options.TaskName))
            {
                WriteVerbose(string.Format(Resources.GBT_GetByName, options.TaskName, options.JobName, options.WorkItemName));
                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    ICloudTask  task   = wiManager.GetTask(options.WorkItemName, options.JobName, options.TaskName, additionalBehaviors: options.AdditionalBehaviors);
                    PSCloudTask psTask = new PSCloudTask(task);
                    return(new PSCloudTask[] { psTask });
                }
            }
            // List Tasks using the specified filter
            else
            {
                if (options.MaxCount <= 0)
                {
                    options.MaxCount = Int32.MaxValue;
                }
                string           jName = options.Job == null ? options.JobName : options.Job.Name;
                ODATADetailLevel odata = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    WriteVerbose(string.Format(Resources.GBT_GetByOData, jName, options.MaxCount));
                    odata = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    WriteVerbose(string.Format(Resources.GBT_GetNoFilter, jName, options.MaxCount));
                }

                IEnumerableAsyncExtended <ICloudTask> tasks = null;
                if (options.Job != null)
                {
                    tasks = options.Job.omObject.ListTasks(odata, options.AdditionalBehaviors);
                }
                else
                {
                    using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                    {
                        tasks = wiManager.ListTasks(options.WorkItemName, options.JobName, odata, options.AdditionalBehaviors);
                    }
                }
                Func <ICloudTask, PSCloudTask> mappingFunction = t => { return(new PSCloudTask(t)); };
                return(new PSAsyncEnumerable <PSCloudTask, ICloudTask>(tasks, mappingFunction).Take(options.MaxCount));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Lists the Task files matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for Task files</param>
        /// <returns>The Task files matching the specified filter options</returns>
        public IEnumerable <PSTaskFile> ListTaskFiles(ListTaskFileOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if ((string.IsNullOrWhiteSpace(options.WorkItemName) || string.IsNullOrWhiteSpace(options.JobName) || string.IsNullOrWhiteSpace(options.TaskName)) &&
                options.Task == null)
            {
                throw new ArgumentNullException(Resources.GBTF_NoTaskSpecified);
            }

            // Get the single Task file matching the specified name
            if (!string.IsNullOrEmpty(options.TaskFileName))
            {
                WriteVerbose(string.Format(Resources.GBTF_GetByName, options.TaskFileName, options.TaskName));
                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    ITaskFile  taskFile   = wiManager.GetTaskFile(options.WorkItemName, options.JobName, options.TaskName, options.TaskFileName, options.AdditionalBehaviors);
                    PSTaskFile psTaskFile = new PSTaskFile(taskFile);
                    return(new PSTaskFile[] { psTaskFile });
                }
            }
            // List Task files using the specified filter
            else
            {
                string           tName = options.Task == null ? options.TaskName : options.Task.Name;
                ODATADetailLevel odata = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    WriteVerbose(string.Format(Resources.GBTF_GetByOData, tName));
                    odata = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    WriteVerbose(string.Format(Resources.GBTF_NoFilter, tName));
                }

                IEnumerableAsyncExtended <ITaskFile> taskFiles = null;
                if (options.Task != null)
                {
                    taskFiles = options.Task.omObject.ListTaskFiles(options.Recursive, odata, options.AdditionalBehaviors);
                }
                else
                {
                    using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                    {
                        taskFiles = wiManager.ListTaskFiles(options.WorkItemName, options.JobName, options.TaskName, options.Recursive, odata, options.AdditionalBehaviors);
                    }
                }
                Func <ITaskFile, PSTaskFile> mappingFunction = f => { return(new PSTaskFile(f)); };
                return(PSAsyncEnumerable <PSTaskFile, ITaskFile> .CreateWithMaxCount(
                           taskFiles, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount))));
            }
        }
        /// <summary>
        /// Lists the vm files matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for vm files</param>
        /// <returns>The vm files matching the specified filter options</returns>
        public IEnumerable <PSVMFile> ListVMFiles(ListVMFileOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            // Get the single vm file matching the specified name
            if (!string.IsNullOrEmpty(options.VMFileName))
            {
                WriteVerbose(string.Format(Resources.GBVMF_GetByName, options.VMFileName, options.VMName));
                using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                {
                    ITaskFile vmFile   = poolManager.GetVMFile(options.PoolName, options.VMName, options.VMFileName, options.AdditionalBehaviors);
                    PSVMFile  psVMFile = new PSVMFile(vmFile);
                    return(new PSVMFile[] { psVMFile });
                }
            }
            // List vm files using the specified filter
            else
            {
                string           vmName           = options.VM == null ? options.VMName : options.VM.Name;
                ODATADetailLevel odata            = null;
                string           verboseLogString = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    verboseLogString = string.Format(Resources.GBVMF_GetByOData, vmName);
                    odata            = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    verboseLogString = string.Format(Resources.GBVMF_NoFilter, vmName);
                }
                WriteVerbose(verboseLogString);

                IEnumerableAsyncExtended <ITaskFile> vmFiles = null;
                if (options.VM != null)
                {
                    vmFiles = options.VM.omObject.ListVMFiles(options.Recursive, odata, options.AdditionalBehaviors);
                }
                else
                {
                    using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                    {
                        vmFiles = poolManager.ListVMFiles(options.PoolName, options.VMName, options.Recursive, odata, options.AdditionalBehaviors);
                    }
                }
                Func <ITaskFile, PSVMFile> mappingFunction = f => { return(new PSVMFile(f)); };
                return(PSAsyncEnumerable <PSVMFile, ITaskFile> .CreateWithMaxCount(
                           vmFiles, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount))));
            }
        }
Esempio n. 5
0
        private async System.Threading.Tasks.Task <List <TvmModel> > ListVMsAsync()
        {
            List <TvmModel> results = new List <TvmModel>();
            IEnumerableAsyncExtended <IVM> jobList         = this.Pool.ListVMs(OptionsModel.Instance.ListDetailLevel);
            IAsyncEnumerator <IVM>         asyncEnumerator = jobList.GetAsyncEnumerator();

            while (await asyncEnumerator.MoveNextAsync())
            {
                results.Add(new TvmModel(this, asyncEnumerator.Current));
            }

            return(results);
        }
Esempio n. 6
0
        /// <summary>
        /// Lists the files on this TVM
        /// </summary>
        /// <returns></returns>
        private async System.Threading.Tasks.Task <List <ITaskFile> > ListFilesAsync()
        {
            List <ITaskFile> results = new List <ITaskFile>();
            IEnumerableAsyncExtended <ITaskFile> vmFiles         = this.VM.ListVMFiles(recursive: true);
            IAsyncEnumerator <ITaskFile>         asyncEnumerator = vmFiles.GetAsyncEnumerator();

            while (await asyncEnumerator.MoveNextAsync())
            {
                results.Add(asyncEnumerator.Current);
            }

            return(results);
        }
Esempio n. 7
0
        internal PSAsyncEnumerable(IEnumerableAsyncExtended <T2> omAsyncEnumerable, Func <T2, T1> mappingFunction)
        {
            if (omAsyncEnumerable == null)
            {
                throw new ArgumentNullException("omAsyncEnumerable");
            }
            this.omAsyncEnumerable = omAsyncEnumerable;

            if (mappingFunction == null)
            {
                throw new ArgumentNullException("mappingFunction");
            }
            this.mappingFunction = mappingFunction;
        }
Esempio n. 8
0
        private async System.Threading.Tasks.Task <List <TaskModel> > ListTasksAsync()
        {
            List <TaskModel> results = new List <TaskModel>();

            IEnumerableAsyncExtended <ICloudTask> taskList        = this.Job.ListTasks(OptionsModel.Instance.ListDetailLevel);
            IAsyncEnumerator <ICloudTask>         asyncEnumerator = taskList.GetAsyncEnumerator();

            while (await asyncEnumerator.MoveNextAsync())
            {
                results.Add(new TaskModel(this, asyncEnumerator.Current));
            }

            return(results);
        }
Esempio n. 9
0
        /// <summary>
        /// Lists the Jobs matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for Jobs</param>
        /// <returns>The Jobs matching the specified filter options</returns>
        public IEnumerable <PSCloudJob> ListJobs(ListJobOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (string.IsNullOrEmpty(options.WorkItemName) && options.WorkItem == null)
            {
                throw new ArgumentNullException(Resources.GBJ_NoWorkItem);
            }
            string wiName = options.WorkItem == null ? options.WorkItemName : options.WorkItem.Name;

            // Get the single Job matching the specified name
            if (!string.IsNullOrEmpty(options.JobName))
            {
                WriteVerbose(string.Format(Resources.GBJ_GetByName, options.JobName, wiName));
                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    ICloudJob  job   = wiManager.GetJob(wiName, options.JobName, additionalBehaviors: options.AdditionalBehaviors);
                    PSCloudJob psJob = new PSCloudJob(job);
                    return(new PSCloudJob[] { psJob });
                }
            }
            // List Jobs using the specified filter
            else
            {
                if (options.MaxCount <= 0)
                {
                    options.MaxCount = Int32.MaxValue;
                }
                ODATADetailLevel odata = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    WriteVerbose(string.Format(Resources.GBJ_GetByOData, wiName, options.MaxCount));
                    odata = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    WriteVerbose(string.Format(Resources.GBJ_GetNoFilter, wiName, options.MaxCount));
                }

                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    IEnumerableAsyncExtended <ICloudJob> jobs            = wiManager.ListJobs(wiName, odata, options.AdditionalBehaviors);
                    Func <ICloudJob, PSCloudJob>         mappingFunction = j => { return(new PSCloudJob(j)); };
                    return(new PSAsyncEnumerable <PSCloudJob, ICloudJob>(jobs, mappingFunction).Take(options.MaxCount));
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Refreshes the status of the VMs from the Batch service.
        /// </summary>
        /// <returns></returns>
        private async Task RefreshVMsAsync()
        {
            // Get the list of pool VM's - can't use this because IVM does not support RecentTasks property yet
            DetailLevel detailLevel = new ODATADetailLevel()
            {
                SelectClause = "recentTasks,state,name"
            };

            IEnumerableAsyncExtended <IVM> vmEnumerableAsync = this.Pool.ListVMs(detailLevel);
            IAsyncEnumerator <IVM>         enumerator        = vmEnumerableAsync.GetAsyncEnumerator();
            List <IVM> vmList = new List <IVM>();

            while (await enumerator.MoveNextAsync())
            {
                vmList.Add(enumerator.Current);
            }

            this.RunningTasks   = 0;
            this.SchedulableVMs = 0;
            foreach (IVM poolVM in vmList)
            {
                if (poolVM.State == TVMState.Idle || poolVM.State == TVMState.Running)
                {
                    this.SchedulableVMs++;
                }

                if (poolVM.State == TVMState.Running && this.Pool.MaxTasksPerVM == 1)
                {
                    this.RunningTasks++;
                }
                else if (this.Pool.MaxTasksPerVM > 1)
                {
                    IEnumerable <TaskInformation> taskInfoList = poolVM.RecentTasks;
                    if (taskInfoList != null)
                    {
                        foreach (TaskInformation ti in taskInfoList)
                        {
                            if (ti.TaskState == TaskState.Running)
                            {
                                this.RunningTasks++;
                            }
                        }
                    }
                }
            }

            Interlocked.Exchange(ref this.vms, vmList); //Threadsafe swap
        }
        private async System.Threading.Tasks.Task <List <JobModel> > ListJobsAsync()
        {
            List <JobModel> results     = new List <JobModel>();
            var             detailLevel = new ODATADetailLevel()
            {
                SelectClause = "name,state,creationTime"
            };
            IEnumerableAsyncExtended <ICloudJob> jobList = this.WorkItem.ListJobs(detailLevel);

            IAsyncEnumerator <ICloudJob> asyncEnumerator = jobList.GetAsyncEnumerator();

            while (await asyncEnumerator.MoveNextAsync())
            {
                results.Add(new JobModel(this, asyncEnumerator.Current));
            }
            return(results);
        }
Esempio n. 12
0
        /// <summary>
        /// Lists the vms matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for vms</param>
        /// <returns>The vms matching the specified filter options</returns>
        public IEnumerable <PSVM> ListVMs(ListVMOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            string poolName = options.Pool == null ? options.PoolName : options.Pool.Name;

            // Get the single vm matching the specified name
            if (!string.IsNullOrEmpty(options.VMName))
            {
                WriteVerbose(string.Format(Resources.GBVM_GetByName, options.VMName, poolName));
                using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                {
                    IVM  vm   = poolManager.GetVM(poolName, options.VMName, additionalBehaviors: options.AdditionalBehaviors);
                    PSVM psVM = new PSVM(vm);
                    return(new PSVM[] { psVM });
                }
            }
            // List vms using the specified filter
            else
            {
                ODATADetailLevel odata            = null;
                string           verboseLogString = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    verboseLogString = string.Format(Resources.GBVM_GetByOData, poolName);
                    odata            = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    verboseLogString = string.Format(Resources.GBVM_NoFilter, poolName);
                }
                WriteVerbose(verboseLogString);

                using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                {
                    IEnumerableAsyncExtended <IVM> vms = poolManager.ListVMs(poolName, odata, options.AdditionalBehaviors);
                    Func <IVM, PSVM> mappingFunction   = v => { return(new PSVM(v)); };
                    return(PSAsyncEnumerable <PSVM, IVM> .CreateWithMaxCount(
                               vms, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount))));
                }
            }
        }
Esempio n. 13
0
        internal static IEnumerable <T1> CreateWithMaxCount(
            IEnumerableAsyncExtended <T2> omAsyncEnumerable, Func <T2, T1> mappingFunction, int maxCount, Action logMaxCount = null)
        {
            PSAsyncEnumerable <T1, T2> asyncEnumerable = new PSAsyncEnumerable <T1, T2>(omAsyncEnumerable, mappingFunction);

            if (maxCount <= 0)
            {
                return(asyncEnumerable);
            }
            else
            {
                if (logMaxCount != null)
                {
                    logMaxCount();
                }
                return(asyncEnumerable.Take(maxCount));
            }
        }
        /// <summary>
        /// Lists the workitems matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for workitems</param>
        /// <returns>The workitems matching the specified filter options</returns>
        public IEnumerable <PSCloudWorkItem> ListWorkItems(ListWorkItemOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            // Get the single WorkItem matching the specified name
            if (!string.IsNullOrWhiteSpace(options.WorkItemName))
            {
                WriteVerbose(string.Format(Resources.GBWI_GetByName, options.WorkItemName));
                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    ICloudWorkItem  workItem   = wiManager.GetWorkItem(options.WorkItemName, additionalBehaviors: options.AdditionalBehaviors);
                    PSCloudWorkItem psWorkItem = new PSCloudWorkItem(workItem);
                    return(new PSCloudWorkItem[] { psWorkItem });
                }
            }
            // List WorkItems using the specified filter
            else
            {
                ODATADetailLevel odata            = null;
                string           verboseLogString = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    verboseLogString = Resources.GBWI_GetByOData;
                    odata            = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    verboseLogString = Resources.GBWI_NoFilter;
                }
                WriteVerbose(verboseLogString);

                using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager())
                {
                    IEnumerableAsyncExtended <ICloudWorkItem> workItems       = wiManager.ListWorkItems(odata, options.AdditionalBehaviors);
                    Func <ICloudWorkItem, PSCloudWorkItem>    mappingFunction = w => { return(new PSCloudWorkItem(w)); };
                    return(PSAsyncEnumerable <PSCloudWorkItem, ICloudWorkItem> .CreateWithMaxCount(
                               workItems, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount))));
                }
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Lists the pools matching the specified filter options
        /// </summary>
        /// <param name="options">The options to use when querying for pools</param>
        /// <returns>The pools matching the specified filter options</returns>
        public IEnumerable <PSCloudPool> ListPools(ListPoolOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            // Get the single pool matching the specified name
            if (!string.IsNullOrWhiteSpace(options.PoolName))
            {
                WriteVerbose(string.Format(Resources.GBP_GetByName, options.PoolName));
                using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                {
                    ICloudPool  pool   = poolManager.GetPool(options.PoolName, additionalBehaviors: options.AdditionalBehaviors);
                    PSCloudPool psPool = new PSCloudPool(pool);
                    return(new PSCloudPool[] { psPool });
                }
            }
            // List pools using the specified filter
            else
            {
                ODATADetailLevel odata            = null;
                string           verboseLogString = null;
                if (!string.IsNullOrEmpty(options.Filter))
                {
                    verboseLogString = Resources.GBP_GetByOData;
                    odata            = new ODATADetailLevel(filterClause: options.Filter);
                }
                else
                {
                    verboseLogString = Resources.GBP_NoFilter;
                }
                WriteVerbose(verboseLogString);

                using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager())
                {
                    IEnumerableAsyncExtended <ICloudPool> pools           = poolManager.ListPools(odata, options.AdditionalBehaviors);
                    Func <ICloudPool, PSCloudPool>        mappingFunction = p => { return(new PSCloudPool(p)); };
                    return(PSAsyncEnumerable <PSCloudPool, ICloudPool> .CreateWithMaxCount(
                               pools, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount))));
                }
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Runs the job manager task.
        /// </summary>
        public async Task RunAsync()
        {
            Console.WriteLine("JobManager for account: {0}, work item: {1}, job: {2} has started...",
                              this.accountName,
                              this.workItemName,
                              this.jobName);
            Console.WriteLine();

            Console.WriteLine("JobManager running with the following settings: ");
            Console.WriteLine("----------------------------------------");
            Console.WriteLine(this.configurationSettings.ToString());

            //Set up the Batch Service credentials used to authenticate with the Batch Service.
            BatchCredentials batchCredentials = new BatchCredentials(
                this.configurationSettings.BatchAccountName,
                this.configurationSettings.BatchAccountKey);

            using (IBatchClient batchClient = BatchClient.Connect(this.configurationSettings.BatchServiceUrl, batchCredentials))
            {
                using (IWorkItemManager workItemManager = batchClient.OpenWorkItemManager())
                {
                    IToolbox toolbox = batchClient.OpenToolbox();

                    //Construct a container SAS to provide the Batch Service access to the files required to
                    //run the mapper and reducer tasks.
                    string containerSas = Helpers.ConstructContainerSas(
                        this.configurationSettings.StorageAccountName,
                        this.configurationSettings.StorageAccountKey,
                        this.configurationSettings.StorageServiceUrl,
                        this.configurationSettings.BlobContainer);

                    //
                    // Submit mapper tasks.
                    //
                    Console.WriteLine("Submitting {0} mapper tasks.", this.configurationSettings.NumberOfMapperTasks);

                    //The collection of tasks to add to the Batch Service.
                    List <ICloudTask> tasksToAdd = new List <ICloudTask>();

                    for (int i = 0; i < this.configurationSettings.NumberOfMapperTasks; i++)
                    {
                        string taskName     = Helpers.GetMapperTaskName(i);
                        string fileBlobName = Helpers.GetSplitFileName(i);
                        string fileBlobPath = Helpers.ConstructBlobSource(containerSas, fileBlobName);

                        string     commandLine       = string.Format("{0} -MapperTask {1}", Constants.TextSearchExe, fileBlobPath);
                        ICloudTask unboundMapperTask = new CloudTask(taskName, commandLine);

                        //The set of files (exe's, dll's and configuration files) required to run the mapper task.
                        IReadOnlyList <string> mapperTaskRequiredFiles = Constants.RequiredExecutableFiles;

                        List <IResourceFile> mapperTaskResourceFiles = Helpers.GetResourceFiles(containerSas, mapperTaskRequiredFiles);

                        unboundMapperTask.ResourceFiles = mapperTaskResourceFiles;

                        tasksToAdd.Add(unboundMapperTask);
                    }

                    //Submit the unbound task collection to the Batch Service.
                    //Use the AddTask method which takes a collection of ICloudTasks for the best performance.
                    await workItemManager.AddTaskAsync(this.workItemName, this.jobName, tasksToAdd);

                    //
                    // Wait for the mapper tasks to complete.
                    //
                    Console.WriteLine("Waiting for the mapper tasks to complete...");

                    //List all the mapper tasks using a name filter.
                    DetailLevel mapperTaskNameFilter = new ODATADetailLevel()
                    {
                        FilterClause = string.Format("startswith(name, '{0}')", Constants.MapperTaskPrefix)
                    };

                    List <ICloudTask> tasksToMonitor = workItemManager.ListTasks(
                        this.workItemName,
                        this.jobName,
                        detailLevel: mapperTaskNameFilter).ToList();

                    //Use the task state monitor to wait for the tasks to complete.
                    ITaskStateMonitor taskStateMonitor = toolbox.CreateTaskStateMonitor();

                    bool timedOut = await taskStateMonitor.WaitAllAsync(tasksToMonitor, TaskState.Completed, TimeSpan.FromMinutes(5));

                    //Get the list of mapper tasks in order to analyze their state and ensure they completed successfully.
                    IEnumerableAsyncExtended <ICloudTask> asyncEnumerable = workItemManager.ListTasks(
                        this.workItemName,
                        this.jobName,
                        detailLevel: mapperTaskNameFilter);
                    IAsyncEnumerator <ICloudTask> asyncEnumerator = asyncEnumerable.GetAsyncEnumerator();

                    //Dump the status of each mapper task.
                    while (await asyncEnumerator.MoveNextAsync())
                    {
                        ICloudTask cloudTask = asyncEnumerator.Current;

                        Console.WriteLine("Task {0} is in state: {1}", cloudTask.Name, cloudTask.State);

                        await Helpers.CheckForTaskSuccessAsync(cloudTask, dumpStandardOutOnTaskSuccess : false);

                        Console.WriteLine();
                    }

                    //If not all the tasks reached the desired state within the timeout then the job manager
                    //cannot continue.
                    if (timedOut)
                    {
                        const string errorMessage = "Mapper tasks did not complete within expected timeout.";
                        Console.WriteLine(errorMessage);

                        throw new TimeoutException(errorMessage);
                    }

                    //
                    // Create the reducer task.
                    //
                    string reducerTaskCommandLine = string.Format("{0} -ReducerTask", Constants.TextSearchExe);

                    Console.WriteLine("Adding the reducer task: {0}", Constants.ReducerTaskName);
                    ICloudTask unboundReducerTask = new CloudTask(Constants.ReducerTaskName, reducerTaskCommandLine);

                    //The set of files (exe's, dll's and configuration files) required to run the reducer task.
                    List <IResourceFile> reducerTaskResourceFiles = Helpers.GetResourceFiles(containerSas, Constants.RequiredExecutableFiles);

                    unboundReducerTask.ResourceFiles = reducerTaskResourceFiles;

                    //Send the request to the Batch Service to add the reducer task.
                    await workItemManager.AddTaskAsync(this.workItemName, this.jobName, unboundReducerTask);

                    //
                    //Wait for the reducer task to complete.
                    //

                    //Get the bound reducer task and monitor it for completion.
                    ICloudTask boundReducerTask = await workItemManager.GetTaskAsync(this.workItemName, this.jobName, Constants.ReducerTaskName);

                    timedOut = await taskStateMonitor.WaitAllAsync(new List <ICloudTask> {
                        boundReducerTask
                    }, TaskState.Completed, TimeSpan.FromMinutes(2));

                    //Refresh the reducer task to get the most recent information about it from the Batch Service.
                    await boundReducerTask.RefreshAsync();

                    //Dump the reducer tasks exit code and scheduling error for debugging purposes.
                    await Helpers.CheckForTaskSuccessAsync(boundReducerTask, dumpStandardOutOnTaskSuccess : true);

                    //Handle the possibilty that the reducer task did not complete in the expected timeout.
                    if (timedOut)
                    {
                        const string errorMessage = "Reducer task did not complete within expected timeout.";

                        Console.WriteLine("Task {0} is in state: {1}", boundReducerTask.Name, boundReducerTask.State);

                        Console.WriteLine(errorMessage);
                        throw new TimeoutException(errorMessage);
                    }

                    //The job manager has completed.
                    Console.WriteLine("JobManager completed successfully.");
                }
            }
        }