Övning – Lägga till kod för att övervaka och logga Azure Batch-jobbförlopp i din app
Klient-API för Batch gör att en app kan övervaka den aktuella statusen för pooler, noder, jobb och uppgifter.
Om du vill slutföra företagets konsolapp för att konvertera videor vill du att appen ska övervakas och rapportera status för filkonverteringarna. Du vill även minska kostnaderna som Batch ger upphov till genom att lägga till möjligheten för appen att ta bort jobben och poolen när videorna har konverterats. För att minska kostnaderna för fillagring vill du även ta bort de uppladdade videofilerna.
Appen söker efter en befintlig pool och skapar en om den inte finns. Jobbet och aktiviteterna startas och övervakas sedan. När aktiviteterna har slutförts visar appen alternativet att ta bort det skapade jobbet och poolen. Appen tar automatiskt bort de uppladdade videorna för att spara på bloblagringskostnader.
Lägga till övervakning
I Cloud Shell redigerar du filen
Program.cs
i redigeringsprogrammet:code Program.cs
Lägg till följande metod,
MonitorTasksAsync()
, i Program.cs för att övervaka jobbuppgifter.private static async Task<bool> MonitorTasksAsync(BatchClient batchClient, string jobId, TimeSpan timeout) { bool allTasksSuccessful = true; const string completeMessage = "All tasks reached state Completed."; const string incompleteMessage = "One or more tasks failed to reach the Completed state within the timeout period."; const string successMessage = "Success! All tasks completed successfully. Output files uploaded to output container."; const string failureMessage = "One or more tasks failed."; Console.WriteLine("Monitoring all tasks for 'Completed' state, timeout in {0}...", timeout.ToString()); // We use a TaskStateMonitor to monitor the state of our tasks. In this case, we will wait for all tasks to // reach the Completed state. IEnumerable<CloudTask> addedTasks = batchClient.JobOperations.ListTasks(JobId); TaskStateMonitor taskStateMonitor = batchClient.Utilities.CreateTaskStateMonitor(); try { await taskStateMonitor.WhenAll(addedTasks, TaskState.Completed, timeout); } catch (TimeoutException) { await batchClient.JobOperations.TerminateJobAsync(jobId); Console.WriteLine(incompleteMessage); return false; } await batchClient.JobOperations.TerminateJobAsync(jobId); Console.WriteLine(completeMessage); // All tasks have reached the "Completed" state, however, this does not guarantee all tasks completed successfully. // Here we further check for any tasks with an execution result of "Failure". // Obtain the collection of tasks currently managed by the job. // Use a detail level to specify that only the "id" property of each task should be populated. // See https://learn.microsoft.com/azure/batch/batch-efficient-list-queries ODATADetailLevel detail = new ODATADetailLevel(selectClause: "executionInfo"); // Filter for tasks with 'Failure' result. detail.FilterClause = "executionInfo/result eq 'Failure'"; List<CloudTask> failedTasks = await batchClient.JobOperations.ListTasks(jobId, detail).ToListAsync(); if (failedTasks.Any()) { allTasksSuccessful = false; Console.WriteLine(failureMessage); } else { Console.WriteLine(successMessage); } return allTasksSuccessful; }
Objektet
TaskStateMonitor
anropas och returneras när tillståndet för alla uppgifter är (TaskState.Completed
). Appen når tidsgränsen om den måste vänta längre äntimeout
-värdet.Den här metoden använder
batchClient.JobOperations.ListTasks
för att hämta det aktuella tillståndet för uppgifter på Batch-kontot. Vi kan filtrera dessa anrop för att endast returnera den information vi behöver genom att skicka enODATADetailLevel
parameter. När alla aktiviteter har slutförts måste koden kontrollera att alla har slutförts, så om du använder ett filter för"executionInfo/result eq 'Failure'"
med anropetListTasks
returneras alla aktiviteter som misslyckades.Lägg till ett anrop i den metoden
MonitorTasksAsync()
inuti using-blocket iMain()
, och lagra den uppgiftslista som returneras från anropet avAddTaskAsync
.using (BatchClient batchClient = BatchClient.Open(sharedKeyCredentials)) { // Create the Batch pool, which contains the compute nodes that execute the tasks. await CreatePoolIfNotExistAsync(batchClient, PoolId); // Create the job that runs the tasks. await CreateJobAsync(batchClient, JobId, PoolId); // Create a collection of tasks and add them to the Batch job. // Provide a shared access signature for the tasks so that they can upload their output // to the Storage container. List<CloudTask> runningTasks = await AddTasksAsync(batchClient, JobId, inputFiles, outputContainerSasUrl); // Monitor task success or failure, specifying a maximum amount of time to wait for // the tasks to complete. await MonitorTasksAsync(batchClient, JobId, TimeSpan.FromMinutes(30)); }
Rensa
Lägg till den här rensningskoden under anropet till metodanropet
MonitorTasks
i användningsblocket.// Delete input container in storage Console.WriteLine("Deleting container [{0}]...", inputContainerName); CloudBlobContainer container = blobClient.GetContainerReference(inputContainerName); await container.DeleteIfExistsAsync(); // Clean up the job (if the user so chooses) Console.WriteLine(); Console.Write("Delete job? [yes] no: "); string response = Console.ReadLine().ToLower(); if (response != "n" && response != "no") { await batchClient.JobOperations.DeleteJobAsync(JobId); } // Clean up the pool (if the user so chooses - do not delete the pool if new batches of videos are ready to process) Console.Write("Delete pool? [yes] no: "); response = Console.ReadLine().ToLower(); if (response != "n" && response != "no") { Console.WriteLine("Deleting pool ..."); await batchClient.PoolOperations.DeletePoolAsync(PoolId); Console.WriteLine("Pool deleted."); }
Föregående kod tar bort indatacontainern, som innehåller alla uppladdade videor.
Terminalen uppmanar sedan användaren att välja att ta bort jobbet och poolen.
batchClient
Gör att appen kan ta bort dessa komponenter.
Testa konsolappen
Högerklicka i kodredigeraren och välj Spara och välj sedan Avsluta.
Skapa och kör appen.
dotnet run
Du bör få utdata som liknar följande:
Creating container [input]. Creating container [output]. Uploading file ~\cutifypets\InputFiles\3.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\2.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\4.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\1.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\5.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\6.mp4 to container [input]... Creating pool [WinFFmpegPool]... Creating job [WinFFmpegJob]... Adding 6 tasks to job [WinFFmpegJob]... Monitoring all tasks for 'Completed' state, timeout in 00:30:00... All tasks reached state Completed. Success! All tasks completed successfully. Output files uploaded to output container. Deleting container [input]... Delete job? [yes] no: y Delete pool? [yes] no: y Sample complete, hit ENTER to exit...
Appen misslyckas dock om jobbet från föregående körning fortfarande finns, eftersom den tidigare appen inte hade jobbrensningskoden. Du kan ta bort jobbet i Azure-portalen eller i Cloud Shell med:
az batch job delete --job-id WinFFmpegJob \ --account-name $BATCH_NAME \ --account-key $BATCH_KEY \ --account-endpoint $BATCH_URL Are you sure you want to perform this operation? (y/n):
I prompten skriver du y.
Konsol-appen körs mycket snabbare den här gången eftersom noderna (tre virtuella datorer som kör Windows 2012) är vilande och väntar på att ett jobb ska köras.
Dricks
Det finns en fullständigt kommenterad och fungerande version av appen på GitHub.