如何在基于事件的设计中使用Azure Batch并终止/清除已完成的作业
使用Azure Batch,我的项目使用带有函数和队列的基于事件的设计将作业添加到池中。 作业完成后,即使所有任务都已完成,它仍处于“活动”状态。
在计时器上触发(单个使用应用服务计划)function,该计时器从队列中读取X量的消息。 function:
- 创建一个池(如果它不存在)
- 创造一份工作
- 将任务添加到该作业
这很好用。 但是,一旦任务完成,即使所有任务都已完成,作业状态仍保持活动状态。 我希望作业终止/清理/将状态设置为“已完成”。
而且我希望我的function是短暂的,不希望任何状态。 所以我没有使用foreach (CloudTask task in job.CompletedTasks())
来等待任务的状态。
另一种方法是使用任务依赖项,这需要batchClient.Utilities.CreateTaskStateMonitor()
,因此需要一个statefull方法。
在基于事件的设计中使用Azure Batch的最佳方法是什么? 具体来说,一旦任务完成,如何终止/清理作业?
一旦所有任务在作业下完成,您就可以使作业“自动完成”。 CloudJob对象上有一个名为OnAllTasksComplete的属性。
在将任务添加到作业时,您最初要将此属性设置为NoAction
(默认值)。 将所有任务添加到作业后,可以将该值更新为TerminateJob
,然后调用Commit()/CommitAsync()
。 请注意,如果保留最初提交的CloudJob,则在修改属性和提交之前,首先需要Refresh()/RefreshAsync()
。 Alternativley你可以GetJob()/GetJobAsync()
,修改,然后提交。
对于基于事件的设计,您可以查看启用批处理服务分析并查看是否适合您的方案。
fpark答案后的最终解决方案:
public class Orchestrator() { public Task ExecuteAsync() { // Create the Batch pool, which contains the compute nodes // that execute the tasks. var pool = await _batchManager.CreatePoolIfNotExistsAsync(); // Create the job that runs the tasks. var job = await _batchManager.CreateJobIfNotExistsAsync(_domain, pool.Id); // Obtain the bound job from the Batch service await job.RefreshAsync(); // Create a collection of tasks and add them to the Batch job. var tasks = await _fileProcessingTasksFactory.CreateAsync(job.Id); // Add the tasks to the job; the tasks are automatically scheduled // for execution on the nodes by the Batch service. await job.AddTaskAsync(tasks); job.OnAllTasksComplete = OnAllTasksComplete.TerminateJob; await job.CommitAsync(); } } public class BatchManager() public async Task CreatePoolIfNotExistsAsync() { // Code to create and return a pool. } public async Task CreateJobIfNotExistsAsync(string domain, string poolId) { // Job id cannot contain : so replace them. var jobId = $"{domain}-{DateTime.UtcNow:s}".Replace(":", "-"); var job = _parameters.BatchClient.JobOperations.CreateJob(); job.Id = jobId; job.PoolInformation = new PoolInformation { PoolId = poolId }; await job.CommitAsync(); return job; } }
如果您尝试直接使用OnAllTasksComplete.TerminateJob
创建作业,您将收到以下错误:
Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed. 2018-03-27 07:57:40.738 +02:00 [Error] "636577269909538505" - Failure while scheduling Azure Batch tasks. System.InvalidOperationException: This object is in an invalid state. Write access is not allowed. at Microsoft.Azure.Batch.PropertyAccessor`1.ThrowIfReadOnly(Boolean overrideReadOnly) at Microsoft.Azure.Batch.PropertyAccessor`1.<>c__DisplayClass19_0.b__0() at Microsoft.Azure.Batch.PropertyAccessController.WriteProperty(Action propertyWriteAction, BindingAccess allowedAccess, String propertyName) at Microsoft.Azure.Batch.PropertyAccessor`1.SetValue(T value, Boolean overrideReadOnly, Boolean overrideAccessControl) at Microsoft.Azure.Batch.CloudJob.set_OnAllTasksComplete(Nullable`1 value) at BatchManager.CreateJobIfNotExist(String domain, String poolId) in C:\ProjectsGitHub\ProjectName\BatchManager.cs:line 107 at FileProcessingOrchestrator.d__6.MoveNext() in C:\ProjectsGitHub\ProjectName\FileProcessingOrchestrator.cs:line 48 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Nnip.Qrs.EdgarDataProcessing.Parallelization.FunctionApp.ScheduleAzureBatchTasks.d__0.MoveNext() in C:\ProjectsGitHub\ProjectName\FunctionApp\ScheduleAzureBatchTasks.cs:line 93 Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed. A ScriptHost error has occurred Exception while executing function: ScheduleAzureBatchTasks. Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed. Exception while executing function: ScheduleAzureBatchTasks Exception while executing function: ScheduleAzureBatchTasks. Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed. Function completed (Failure, Id=6173b9d2-5058-4a6d-9406-1cf00340774e, Duration=71076ms) Executed 'ScheduleAzureBatchTasks' (Failed, Id=6173b9d2-5058-4a6d-9406-1cf00340774e) System.Private.CoreLib: Exception while executing function: ScheduleAzureBatchTasks. Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed. Function had errors. See Azure WebJobs SDK dashboard for details. Instance ID is '6173b9d2-5058-4a6d-9406-1cf00340774e' System.Private.CoreLib: Exception while executing function: ScheduleAzureBatchTasks. Microsoft.Azure.Batch: This object is in an invalid state. Write access is not allowed.
因此,在添加所有任务后设置job.OnAllTasksComplete
。
在Completed
所有任务后,作业将其状态设置为“ Completed
大约需要两分钟(在我的情况下)。