Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
318 views
in Technique[技术] by (71.8m points)

visual studio - Asynchronous callback not working in VSTS/Azure DevOps

In the release pipeline we're making REST call using InvokeRESTAPI@1, and then in the REST service implementation trying to raise "TaskStartedEvent" and the append logs. The problem is -in the azure devops we see task as pending and not started and we do not see our logs. It is strange as TaskCompletedEvent works fine, we were able to fail of successfully complete the task.

Here is the full code - input params are taken from the REST API call that is made this way - in task definition we put information to the headers:

{
"Content-Type":"application/json", 
"PlanUrl": "$(system.CollectionUri)", 
"ProjectId": "$(system.TeamProjectId)", 
"HubName": "$(system.HostType)", 
"PlanId": "$(system.PlanId)", 
"JobId": "$(system.JobId)", 
"TimelineId": "$(system.TimelineId)", 
"TaskInstanceId": "$(system.TaskInstanceId)", 
"AuthToken": "$(system.AccessToken)"
}

And then read it from headers

    [ApiController]
    public class DatabaseUpdaterController : ControllerBase
    {
        [HttpPost("updateDatabase")]
        public async Task UpdateDatabase()
        {
            string projectId = this.Request.Headers["ProjectId"];
            string planId = this.Request.Headers["PlanId"];
            string jobId = this.Request.Headers["JobId"];
            string timelineId = this.Request.Headers["TimelineId"];
            string taskInstanceId = this.Request.Headers["TaskInstanceId"];
            string hubName = this.Request.Headers["HubName"];
            string taskInstanceName = this.Request.Headers["TaskInstanceName"];
            string planUrl = this.Request.Headers["PlanUrl"];
            string authToken = this.Request.Headers["AuthToken"];

            // Ensure projectId, planId, jobId, timelineId, taskInstanceId are proper guids.

            var credentials = new VssBasicCredential("", authToken);
            var azureDevOpsConnection = new VssConnection(
                new Uri(planUrl),
                credentials);

            var taskClient = azureDevOpsConnection.GetClient<TaskHttpClient>();

            // Handover time consuming work to another task. Completion event should be set to "Callback" in pipeline task.
            Task.Run(() => MyApp.ExecuteAsync(
                taskClient,
                projectId,
                planUrl,
                hubName,
                planId,
                jobId,
                timelineId,
                taskInstanceId,
                taskInstanceName,
                authToken));
        }
    }

In the Application Insights, I see the calls are actually made and the status code returned is 204

        internal static async void ExecuteAsync(
            TaskHttpClient taskClient,
            string projectId,
            string planUri,
            string hubName,
            string planId,
            string jobId,
            string timelineId,
            string taskInstanceId,
            string taskInstanceName,
            string authToken)
        {
            using var httpClient = new HttpClient();

            try
            {
                logger.LogInfo("Azure deploy callback started");

                await taskClient.RaisePlanEventAsync(
                    Guid.Parse(projectId),
                    hubName,
                    Guid.Parse(planId),
                    new TaskStartedEvent(
                        Guid.Parse(jobId),
                        Guid.Parse(taskInstanceId)));

                await taskClient.AppendTimelineRecordFeedAsync(
                    Guid.Parse(projectId),
                    hubName,
                    Guid.Parse(planId),
                    Guid.Parse(timelineId),
                    Guid.Parse(jobId),
                    Guid.Parse(taskInstanceId),
                    new[] { "Task Started" });

                // Do work
                for (int i = 0; i < 10; i++)
                {
                    var logMessage = $"{DateTime.UtcNow:O} Message {i}";

                    await taskClient.AppendTimelineRecordFeedAsync(
                        Guid.Parse(projectId),
                        hubName,
                        Guid.Parse(planId),
                        Guid.Parse(timelineId),
                        Guid.Parse(jobId),
                        Guid.Parse(taskInstanceId),
                        new[] { logMessage });

                    Thread.Sleep(1000);
                }

                logger.LogInfo("Azure deploy callback: long sleep started");
                Thread.Sleep(1000 * 60 * 60 * 4);
                logger.LogInfo("Azure deploy callback: long sleep finished");

                // Work completed now send task completed event state to mark task completed with succeeded/failed status
                await taskClient.RaisePlanEventAsync(
                    Guid.Parse(projectId),
                    hubName,
                    Guid.Parse(planId),
                    new TaskCompletedEvent(
                        Guid.Parse(jobId),
                        Guid.Parse(taskInstanceId),
                        TaskResult.Succeeded));

            }
            catch (Exception exception)
            {
                logger.LogError(exception);

                // send task started message feed and log the message. You will see feed messages in task log UI.
                await taskClient.AppendTimelineRecordFeedAsync(
                    Guid.Parse(projectId),
                    hubName,
                    Guid.Parse(planId),
                    Guid.Parse(timelineId),
                    Guid.Parse(jobId),
                    Guid.Parse(taskInstanceId),
                    new[] { exception.ToString() });

                // Work completed now send task completed event with status 'failed' to mark task failed
                await taskClient.RaisePlanEventAsync(
                    Guid.Parse(projectId),
                    hubName,
                    Guid.Parse(planId),
                    new TaskCompletedEvent(
                        Guid.Parse(jobId),
                        Guid.Parse(taskInstanceId),
                        TaskResult.Failed));

            }
        }

Any ideas why TaskStartedEvent might not work and the task stays in the pending state or why log entries are not uploaded/appended are very welcome

question from:https://stackoverflow.com/questions/65927832/asynchronous-callback-not-working-in-vsts-azure-devops

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...