有没有办法在 Azure Durable Functions 的持久实体中安排“提醒”?

Sam*_*tte 2 azure actor azure-functions azure-durable-functions

我在一个研究项目中使用 Azure Durable Functions,我想验证在持久实体中实现计时器/提醒概念的最佳方法是什么。

在 Service Fabric 中,Actor 可以安排“持久计时器”,以便框架可以调用 Actor 本身的方法。我正在寻找类似的概念。

考虑为我的系统中的每个设备创建的持久实体。我希望每个参与者都按计划运行功能,并自行安排。(我想避免拥有需要为每个设备安排任务的编排功能,并且只需让实体自行运行任务)。

这是允许的、可能的或预见的事情吗?

希望这个问题足够清楚,但很乐意在需要时提供更多背景信息。

Pet*_*ons 5

来自文档

要调用实体上的操作,请指定 [...] 计划时间,它是用于指定操作的交付时间的可选参数。例如,可以可靠地安排操作在未来几天运行。因此有一个选项可以安排实体的调用

但是,您希望从持久实体内部进行安排。这也可以通过使用Entity.Current.SignalEntity文档)来实现。此方法作为重载,接受 DateTime,该 DateTime 指定开始操作的时间。

下面的代码将使用 http 触发函数开始递增计数器。在 azure 函数首次启动后,实体将每 5 秒为自己安排一次操作。

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionApp3
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            [DurableClient] IDurableEntityClient client,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            // Tell the Durable Entity to increase a counter
            await client.SignalEntityAsync<ICounter>("aKey", e => e.IncreaseCount(1));

            return new OkResult();
        }
    }

    public interface ICounter
    {
        void IncreaseCount(int amount);
    }

    [JsonObject(MemberSerialization.OptIn)]
    public class Counter : ICounter
    {
        private readonly ILogger _log;

        public Counter(ILogger<Counter> log)
        {
            _log = log;
        }

        [JsonProperty("value")]
        public int CurrentValue { get; set; }

        public void IncreaseCount(int amount)
        {
            this.CurrentValue += amount;

            if(this.CurrentValue) > 10
                 return;

            // Schedule a call to this entity to IncreaseCount after 5 seconds. 
            // Once the method is called, schedule it again to create the effect of a timer
            Entity.Current.SignalEntity<ICounter>(Entity.Current.EntityId, DateTime.Now.AddSeconds(5), e => e.IncreaseCount(1));
            _log.LogInformation(this.CurrentValue.ToString());
        }

        [FunctionName(nameof(Counter))]
        public static Task Run([EntityTrigger] IDurableEntityContext ctx)
        {
            return ctx.DispatchAsync<Counter>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这只是一个粗略的示例,但要点是 Entity.Current.SignalEntity实体本身使用它来安排工作。

  • 持久实体的好处之一是方法是串行执行的,一次一个,以防止竞争条件。这意味着多个进程不能同时更新同一实体。如果您要使用表存储并且在方法中改变多行,则必须处理可能的并发问题。请参阅 https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-entities?tabs=csharp#comparison-with-virtual-actors 和 https://dev.to/azure /深入研究带有 azure-functions-173e 的持久实体 (3认同)