Övning – Lägga till kod för att övervaka och logga Azure Batch-jobbförlopp i din app

Slutförd

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

  1. I Cloud Shell redigerar du filen Program.cs i redigeringsprogrammet:

    code Program.cs
    
  2. 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 än timeout-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 en ODATADetailLevel 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 anropet ListTasks returneras alla aktiviteter som misslyckades.

  3. Lägg till ett anrop i den metoden MonitorTasksAsync() inuti using-blocket i Main(), och lagra den uppgiftslista som returneras från anropet av AddTaskAsync.

    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

  1. 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

  1. Högerklicka i kodredigeraren och välj Spara och välj sedan Avsluta.

  2. Skapa och kör appen.

    dotnet run
    
  3. 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...
    
  4. 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.

  5. 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.