polling for task status.
This commit is contained in:
parent
e6561308e5
commit
2a8f4cbb8d
@ -1,4 +1,7 @@
|
|||||||
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using FarmmapsApi.HttpMessageHandlers;
|
using FarmmapsApi.HttpMessageHandlers;
|
||||||
using FarmmapsApi.Models;
|
using FarmmapsApi.Models;
|
||||||
using FarmmapsApi.Services;
|
using FarmmapsApi.Services;
|
||||||
@ -9,7 +12,8 @@ namespace FarmmapsApi
|
|||||||
{
|
{
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddFarmmapsServices(this IServiceCollection serviceCollection, Configuration configuration)
|
public static IServiceCollection AddFarmmapsServices(this IServiceCollection serviceCollection,
|
||||||
|
Configuration configuration)
|
||||||
{
|
{
|
||||||
return serviceCollection
|
return serviceCollection
|
||||||
.AddSingleton(configuration)
|
.AddSingleton(configuration)
|
||||||
@ -23,7 +27,26 @@ namespace FarmmapsApi
|
|||||||
.AddTransient<FarmmapsAuthenticationHandler>()
|
.AddTransient<FarmmapsAuthenticationHandler>()
|
||||||
.AddHttpClient<FarmmapsApiService>()
|
.AddHttpClient<FarmmapsApiService>()
|
||||||
.AddHttpMessageHandler<FarmmapsAuthenticationHandler>()
|
.AddHttpMessageHandler<FarmmapsAuthenticationHandler>()
|
||||||
.Services;;
|
.Services;
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task PollTask(TimeSpan retryTime, Func<CancellationTokenSource, Task> callback)
|
||||||
|
{
|
||||||
|
var tokenSource = new CancellationTokenSource();
|
||||||
|
var token = tokenSource.Token;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await callback(tokenSource);
|
||||||
|
await Task.Delay(retryTime, token);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
} while (!token.IsCancellationRequested);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,8 +11,9 @@ using System.Threading.Tasks;
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
using FarmmapsApi.Models;
|
using FarmmapsApi.Models;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
|
using Microsoft.AspNetCore.Http.Connections;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ namespace FarmmapsApi.Services
|
|||||||
{
|
{
|
||||||
public class FarmmapsApiService
|
public class FarmmapsApiService
|
||||||
{
|
{
|
||||||
|
private readonly ILogger<FarmmapsApiService> _logger;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly OpenIdConnectService _openIdConnectService;
|
private readonly OpenIdConnectService _openIdConnectService;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
@ -28,9 +30,10 @@ namespace FarmmapsApi.Services
|
|||||||
|
|
||||||
public event Action<EventMessage> EventCallback;
|
public event Action<EventMessage> EventCallback;
|
||||||
|
|
||||||
public FarmmapsApiService(HttpClient httpClient,
|
public FarmmapsApiService(HttpClient httpClient, ILogger<FarmmapsApiService> logger,
|
||||||
OpenIdConnectService openIdConnectService, Configuration configuration)
|
OpenIdConnectService openIdConnectService, Configuration configuration)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_openIdConnectService = openIdConnectService;
|
_openIdConnectService = openIdConnectService;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
@ -65,13 +68,21 @@ namespace FarmmapsApi.Services
|
|||||||
var uri = new Uri(_configuration.Endpoint);
|
var uri = new Uri(_configuration.Endpoint);
|
||||||
var eventEndpoint = $"{uri.Scheme}://{uri.Host}:{uri.Port}/EventHub";
|
var eventEndpoint = $"{uri.Scheme}://{uri.Host}:{uri.Port}/EventHub";
|
||||||
_hubConnection = new HubConnectionBuilder()
|
_hubConnection = new HubConnectionBuilder()
|
||||||
.WithUrl(eventEndpoint)
|
.WithUrl(eventEndpoint, HttpTransportType.WebSockets,
|
||||||
|
options => options.SkipNegotiation = true)
|
||||||
|
.ConfigureLogging(log => log.AddConsole())
|
||||||
.WithAutomaticReconnect()
|
.WithAutomaticReconnect()
|
||||||
.AddJsonProtocol()
|
|
||||||
.Build();
|
.Build();
|
||||||
_hubConnection.On("Event", (EventMessage @event) => EventCallback?.Invoke(@event));
|
|
||||||
|
|
||||||
await _hubConnection.StartAsync();
|
await _hubConnection.StartAsync();
|
||||||
|
await AuthenticateEventHub(accessToken);
|
||||||
|
|
||||||
|
_hubConnection.Reconnected += async s => await AuthenticateEventHub(accessToken);
|
||||||
|
_hubConnection.On("event", (Object @event) => _logger.LogInformation(@event.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AuthenticateEventHub(string accessToken)
|
||||||
|
{
|
||||||
await _hubConnection.SendAsync("authenticate", accessToken);
|
await _hubConnection.SendAsync("authenticate", accessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ using FarmmapsApi.Models;
|
|||||||
using FarmmapsApi.Services;
|
using FarmmapsApi.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using static FarmmapsApi.Extensions;
|
||||||
|
|
||||||
namespace FarmmapsApiSamples
|
namespace FarmmapsApiSamples
|
||||||
{
|
{
|
||||||
@ -44,30 +45,10 @@ namespace FarmmapsApiSamples
|
|||||||
|
|
||||||
if (myDriveRoot != null)
|
if (myDriveRoot != null)
|
||||||
{
|
{
|
||||||
// create or get a cropfield
|
var cropfieldItem = await GetOrCreateCropfieldItem(myDriveRoot.Code);
|
||||||
var cropfieldItem = await GetCreateCropfieldItem(myDriveRoot.Code);
|
var targetN = await CalculateTargetN(cropfieldItem, 60);
|
||||||
|
|
||||||
// create or get target n item
|
_logger.LogInformation($"TargetN: {targetN}");
|
||||||
|
|
||||||
var targetNItems = await
|
|
||||||
_farmmapsApiService.GetItemChildrenAsync(myDriveRoot.Code, USERINPUT_ITEMTYPE);
|
|
||||||
|
|
||||||
Item targetNItem;
|
|
||||||
if (targetNItems.Count == 0)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Creating targetN item");
|
|
||||||
var itemRequest = CreateTargetNItemRequest(myDriveRoot.Code);
|
|
||||||
targetNItem = await _farmmapsApiService.CreateItemAsync(itemRequest);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
targetNItem = targetNItems[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
await CalculateTargetN(cropfieldItem, targetNItem, 60);
|
|
||||||
|
|
||||||
|
|
||||||
await Task.Delay(2000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -76,7 +57,7 @@ namespace FarmmapsApiSamples
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Item> GetCreateCropfieldItem(string parentItemCode)
|
private async Task<Item> GetOrCreateCropfieldItem(string parentItemCode)
|
||||||
{
|
{
|
||||||
var cropfieldItems = await
|
var cropfieldItems = await
|
||||||
_farmmapsApiService.GetItemChildrenAsync(parentItemCode, "vnd.farmmaps.itemtype.cropfield");
|
_farmmapsApiService.GetItemChildrenAsync(parentItemCode, "vnd.farmmaps.itemtype.cropfield");
|
||||||
@ -101,8 +82,25 @@ namespace FarmmapsApiSamples
|
|||||||
return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest);
|
return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Item> CalculateTargetN(Item cropfieldItem, Item targetNItem, int targetYield)
|
private async Task<double> CalculateTargetN(Item cropfieldItem, int targetYield)
|
||||||
{
|
{
|
||||||
|
var targetNItems = await
|
||||||
|
_farmmapsApiService.GetItemChildrenAsync(cropfieldItem.ParentCode, USERINPUT_ITEMTYPE);
|
||||||
|
|
||||||
|
Item targetNItem;
|
||||||
|
if (targetNItems.Count == 0)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Creating targetN item");
|
||||||
|
var itemRequest = CreateTargetNItemRequest(cropfieldItem.ParentCode);
|
||||||
|
targetNItem = await _farmmapsApiService.CreateItemAsync(itemRequest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetNItem = targetNItems[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation($"Calculating targetN with targetYield: {targetYield}");
|
||||||
|
|
||||||
var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK};
|
var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK};
|
||||||
nbsTargetNRequest.attributes["operation"] = "targetn";
|
nbsTargetNRequest.attributes["operation"] = "targetn";
|
||||||
nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code;
|
nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code;
|
||||||
@ -111,11 +109,19 @@ namespace FarmmapsApiSamples
|
|||||||
nbsTargetNRequest.attributes["targetYield"] = targetYield.ToString();
|
nbsTargetNRequest.attributes["targetYield"] = targetYield.ToString();
|
||||||
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsTargetNRequest);
|
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsTargetNRequest);
|
||||||
|
|
||||||
// poll task
|
await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) =>
|
||||||
|
{
|
||||||
|
var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
|
||||||
|
|
||||||
// get target N item again
|
if (itemTask.State != ItemTaskState.Processing && itemTask.State != ItemTaskState.Scheduled)
|
||||||
|
tokenSource.Cancel();
|
||||||
|
});
|
||||||
|
|
||||||
return targetNItem;
|
var item = await _farmmapsApiService.GetItemAsync(targetNItem.Code);
|
||||||
|
if (item.Data.ContainsKey("TargetN"))
|
||||||
|
return item.Data["TargetN"].Value<double>();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemRequest CreateTargetNItemRequest(string parentItemCode)
|
private ItemRequest CreateTargetNItemRequest(string parentItemCode)
|
||||||
|
Loading…
Reference in New Issue
Block a user