Как использовать функции Azure для получения только новых данных - PullRequest
0 голосов
/ 10 июля 2019

Я использую функции Azure для периодического получения счетов от третьих лиц, использующих его API, и ищу лучший способ получить только новые счета.

Прямо сейчас моя функция извлекает все счета за прошедший день, и мой код проверяет, что остальная часть обработки еще не была выполнена, прежде чем делать это. Я на 100% уверен, что есть лучший способ сделать это. Я бы хотел, чтобы решение было надежным, а это не так. Есть ли способ использовать контрольные точки и узнать, что было получено или нет?

        [FunctionName(FunctionNames.GetInvoicesAsync)]
        public async static Task<ReadOnlyCollection<InvoiceContent>> GetInvoicesAsync([ActivityTrigger] string name)
        {
            var begin = DateTime.UtcNow.AddDays(-1);
            var end = DateTime.UtcNow;

            var thirdPartyClient = ClientHelper.GetThirdPartyClient();
            return await thirdPartyClient.GetInvoicesAsync(begin, end);
        }

Я бы хотел, чтобы переменная "begin" была последним успешным выполнением функции или что-то в этом роде.

Спасибо!

1 Ответ

0 голосов
/ 10 июля 2019

Я собрал небольшой небольшой пример кода сохранения ваших функций. Я использовал триггер HTTP, поскольку он облегчил тестирование, но логика хранения таблиц была бы такой же в вашем триггере Activity.

public class FunctionExecution : TableEntity
{
    public string FunctionName { get; set; }
}

public static class HttpTriggeredFunction
{
    [FunctionName("HttpTriggeredFunction")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        [Table("FunctionExecutions", Connection = "StorageConnectionString")] CloudTable table,
        ExecutionContext executionContext,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        // query table storage for all entries (you might want to restrict the query to the last day etc)
        TableQuery<FunctionExecution> query = new TableQuery<FunctionExecution>();
        TableQuerySegment<FunctionExecution> data = await table.ExecuteQuerySegmentedAsync(query, null);

        // get the last function execution by ordering by Timestamp
        FunctionExecution lastFunctionExecution = data.OrderByDescending(r => r.Timestamp).FirstOrDefault();

        DateTimeOffset? begin = lastFunctionExecution?.Timestamp;
        DateTime end = DateTime.UtcNow;

        // call off to ThirdPartyClient

        // log successful execution to table storage
        TableOperation insertOperation = TableOperation.Insert(new FunctionExecution
        {
            PartitionKey = executionContext.InvocationId.ToString(), // using the InvocationId of the function so you can relate executions if needed
            RowKey = Guid.NewGuid().ToString(), 
            Timestamp = DateTimeOffset.UtcNow, // set the Timestamp to now as the function has been successful
            FunctionName = "HttpTriggeredFunction" // optional but you might want to save the function name in your case FunctionNames.GetInvoicesAsync
        });

        await table.ExecuteAsync(insertOperation);

        return new OkObjectResult(null);
    }
}

Редактировать : Подумал - возможно, вы захотите установить имя функции в качестве ключа разделения, чтобы обеспечить лучшее разбиение (при необходимости):

TableOperation insertOperation = TableOperation.Insert(new FunctionExecution
{
    PartitionKey = "HttpTriggeredFunction", // a partition is a consecutive range of entities possessing the same partition key value
    RowKey = Guid.NewGuid().ToString(), // row key must be unique within a partition
    Timestamp = DateTimeOffset.UtcNow, // set the Timestamp to now as the function has been successful
    InvocationId = executionContext.InvocationId.ToString() // optional - using the InvocationId of the function so you can relate executions if needed
});

Надеюсь, это поможет!

...