问题描述
在 Microsoft Azure 逻辑应用程序中,我有一个 do until 循环,它循环获取请求,直到它完成。但是 HTTP Get 请求给出了以下与超时有关的错误。似乎即使在 2 分钟内重试 4 次,http get 请求也会超时。
错误请求。 Http请求失败:服务器没有响应 超时限制。请参阅逻辑应用限制在 https://aka.ms/logic-apps-limits-and-config#http-limits。
操作失败。一个动作失败。没有依赖操作成功。
发生了 4 次重试。
直到循环控制详述
解决方法
如果打开Asynchronous Pattern
后还是不行,应该是你的API
没有按照asynchronous polling pattern
设计。
从这张图可以知道,你的API需要先返回202
,响应头需要包含location
,这个location
就是Azure轮询的URL地址逻辑应用。
请参考the following sample,但此示例可能有点过时,您可以参考它来设计您的 API。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
namespace AsyncResponse.Controllers
{
public class AsyncController : ApiController
{
//State dictionary for sample - stores the state of the working thread
private static Dictionary<Guid,bool> runningTasks = new Dictionary<Guid,bool>();
/// <summary>
/// This is the method that starts the task running. It creates a new thread to complete the work on,and returns an ID which can be passed in to check the status of the job.
/// In a real world scenario your dictionary may contain the object you want to return when the work is done.
/// </summary>
/// <returns>HTTP Response with needed headers</returns>
[HttpPost]
[Route("api/startwork")]
public async Task<HttpResponseMessage> longrunningtask()
{
Guid id = Guid.NewGuid(); //Generate tracking Id
runningTasks[id] = false; //Job isn't done yet
new Thread(() => doWork(id)).Start(); //Start the thread of work,but continue on before it completes
HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.Accepted);
responseMessage.Headers.Add("location",String.Format("{0}://{1}/api/status/{2}",Request.RequestUri.Scheme,Request.RequestUri.Host,id)); //Where the engine will poll to check status
responseMessage.Headers.Add("retry-after","20"); //How many seconds it should wait (20 is default if not included)
return responseMessage;
}
/// <summary>
/// This is where the actual long running work would occur.
/// </summary>
/// <param name="id"></param>
private void doWork(Guid id)
{
Debug.WriteLine("Starting work");
Task.Delay(120000).Wait(); //Do work will work for 120 seconds)
Debug.WriteLine("Work completed");
runningTasks[id] = true; //Set the flag to true - work done
}
/// <summary>
/// Method to check the status of the job. This is where the location header redirects to.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[Route("api/status/{id}")]
[Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.BadRequest,"No job exists with the specified id")]
[Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.Accepted,"The job is still running")]
[Swashbuckle.Swagger.Annotations.SwaggerResponse(HttpStatusCode.OK,"The job has completed")]
public HttpResponseMessage checkStatus([FromUri] Guid id)
{
//If the job is complete
if(runningTasks.ContainsKey(id) && runningTasks[id])
{
runningTasks.Remove(id);
return Request.CreateResponse(HttpStatusCode.OK,"Some data could be returned here");
}
//If the job is still running
else if(runningTasks.ContainsKey(id))
{
HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.Accepted);
responseMessage.Headers.Add("location",id)); //Where the engine will poll to check status
responseMessage.Headers.Add("retry-after","20");
return responseMessage;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest,"No job exists with the specified ID");
}
}
}
}