I want to call one 3rd party Rest API from the asp.net core application with the polling mechanism.
Here in the below sample code, I want to call _client.DocumentProcess(model) API with some polling mechanism after every 10 seconds for five times until I get the Result as "Success" or my polling call limit gets exceeded.
public async Task<Result> TrackDocumentProcess(RequestModel model)
{
var response = await _client.DocumentProcess(model);
if(response.IsSuccess)
{
if(response.Value.Status != "Success")
//Call the _client.DocumentProcess(model) API after 10 seconds.
else
return Result.Success();
}
}
public async Task<Result<ResponseModel>> DocumentProcess(RequestModel model)
{
var authToken = GetToken();
using var httpClient = new HttpClient();
using var request = new HttpRequestMessage(new HttpMethod("POST"), $"https://apiurl.com/api/TrackDocumentProcessStatus/{model.DocumentId}");
request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {authToken.Result.Value.Token}");
var response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(content))
{
var userRequestResponse = JsonSerializer.Deserialize<ResponseModel>(content);
return Result.Success(userRequestResponse);
}
return Result.Failure<ResponseModel>("Error...");
}
Can you please suggest any best practices to solve this problem? Thanks.
Here in the below sample code, I want to call _client.DocumentProcess(model) API with some pooling mechanism after every 10 seconds for five times until I get the Result as "Success" or my pooling call limit gets exceeded.
Well based on your scenario, we can consider two standard implementaion. First one we can implement using PeriodicTimer which provides a periodic timer that would call as per the given time interval.
Another one, would be using BackgroundService worker process which would continue calling API unless the certain condition are meet.
Using PeriodicTimer:
public async Task<IActionResult> DocumentProcess()
{
var status = await TrackDocumentProcessStatus();
if (status == "Success")
{
return Ok(status);
}
else
{
var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
while (await timer.WaitForNextTickAsync())
{
status = await TrackDocumentProcessStatus();
if (status == "Success")
{
break;
}
continue;
}
}
return Ok();
}
Explanation:
As you can see, when DocumentProcess method would invocke, it will call the TrackDocumentProcessStatus method thus, the API and if API return pending it update the status and will call again within next 10 seconds and process would continue until it gets success status.
Method Would Invoked Every 10 Seconds:
public async Task<string> TrackDocumentProcessStatus()
{
var rquestObject = new StatusRequestModel();
rquestObject.RequestId = 3;
var data_ = JsonConvert.SerializeObject(rquestObject);
HttpClient _httpClient = new HttpClient();
var buffer_ = System.Text.Encoding.UTF8.GetBytes(data_);
var byteContent_ = new ByteArrayContent(buffer_);
byteContent_.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string _urls = "http://localhost:5094/api/Rest/CheckDocumentStatus";
var responses_ = await _httpClient.PostAsync(_urls, byteContent_);
if (responses_.StatusCode != HttpStatusCode.OK)
{
return "Pending";
}
string response = await responses_.Content.ReadAsStringAsync();
return response;
}
Output:
Note: If you would like to know more details on it you could check our official document here
BackgroundService worker process:
It would be a individual background worker service which would continue running and check your status behind. You can achieve your requirement as following:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
var status = await TrackDocumentProcessStatus();
status = await TrackDocumentProcessStatus();
if (status == "Success")
{
break;
}
Console.WriteLine(status);
await Task.Delay(1000, stoppingToken);
}
}
public async Task<string> TrackDocumentProcessStatus()
{
var rquestObject = new StatusRequestModel();
rquestObject.RequestId = 1;
var data_ = JsonConvert.SerializeObject(rquestObject);
HttpClient _httpClient = new HttpClient();
var buffer_ = System.Text.Encoding.UTF8.GetBytes(data_);
var byteContent_ = new ByteArrayContent(buffer_);
byteContent_.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string _urls = "http://localhost:5094/api/Rest/CheckDocumentStatus";
var responses_ = await _httpClient.PostAsync(_urls, byteContent_);
if (responses_.StatusCode != HttpStatusCode.OK)
{
return "Pending";
}
string response = await responses_.Content.ReadAsStringAsync();
return response;
}
Note: Both implementaion would call your API after a certain interval for checking status from another API. The difference of these implementation is background worker service would continue in background, no other action wwould required just like widows service, If you would like to know more details on background worker service you could check our official document here