Запланированный сигнал для надежного объекта срабатывает немедленно в надежных функциях Azure

#c# #azure #azure-functions #azure-durable-functions

#c# #azure #azure-функции #azure-durable-функции

Вопрос:

Я хочу иметь очень легкий подход, при котором я предоставляю конечную точку HTTP (триггер), которая в некоторой степени предоставляет доступ к долговременному объекту (субъекту) и заставляет субъекта выполнять работу на регулярной основе.

Логика в моем HTTP-триггере выглядит следующим образом:

  1. Проверьте, существует ли объект с uid уже
  2. Если нет, подайте сигнал объекту и запустите InitializeMonitoringAsync метод для субъекта
  3. Если да, вызовите состояние объекта для субъекта и верните некоторые значения
  4. После инициализации субъект (долговременная сущность) должен часто вызывать RefreshActionAsync самостоятельно.

Проблема, с которой я сталкиваюсь, заключается в том, что метод обновления, похоже, продолжает выполняться постоянно, без учета настроенных задержек. Чего мне не хватает?

Обновление (обходной путь):

По-видимому, когда я меняю методы интерфейса (которые теперь возвращают a Task ) на методы, которые возвращают void (и я меняю вызов signal на : e => e.RefreshActionAsync() ), тогда, похоже, это работает. Но я не понимаю, почему, и это, похоже, тоже не является документированным ограничением.

Приведенный ниже код:

Интерфейс сущности

 public interface IReproEntity
{
    Task RefreshActionAsync();
    Task InitializeMonitoringAsync();
}
  

Функция объекта

 [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class ReproEntity : IReproEntity
{
    [JsonProperty] public bool Activated { get; set; }
    [JsonProperty] public int LoopCount { get; set; }

    public Task InitializeMonitoringAsync()
    {
        ScheduleNext(DateTime.UtcNow.AddSeconds(10));
        Activated = true;
        return Task.CompletedTask;
    }

    public Task RefreshActionAsync()
    {
        LoopCount  = 1;
        ScheduleNext();
        return Task.CompletedTask;
    }

    private void ScheduleNext(DateTime nextSchedule = default)
    {
        if (nextSchedule == default) nextSchedule = DateTime.UtcNow.AddSeconds(30);
        Entity.Current.SignalEntity<IReproEntity>(Entity.Current.EntityId, nextSchedule,
            async (e) => await e.RefreshActionAsync());
    }

    [FunctionName(nameof(ReproEntity))]
    public static Task Run([EntityTrigger] IDurableEntityContext ctx)
    {
        return ctx.DispatchAsync<ReproEntity>();
    }
}
  

Функция запуска HTTP

 [FunctionName("Repro_HttpStart")]
public async Task<IActionResult> HttpStart(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "repro/{uid}")]
    HttpRequest req, string uid,
    [DurableClient] IDurableEntityClient entityClient,
    ILogger log)
{
    var entityId = new EntityId(nameof(ReproEntity), uid);
    var entityState = await entityClient.ReadEntityStateAsync<ReproEntity>(entityId);
    if (!(entityState.EntityExists amp;amp; entityState.EntityState.Activated))
    {
        await entityClient.SignalEntityAsync(entityId, nameof(IReproEntity.InitializeMonitoringAsync));

        return new NotFoundObjectResult(new {error = $"The actor {uid} does not exist"});
    }

    return new OkObjectResult(new
    {
        entityState.EntityState.LoopCount, entityState.EntityState.Activated
    });
}
  

Комментарии:

1. К вашему сведению, для всех, кто еще сталкивается с этой проблемой, эта проблема была исправлена в версии 2.2.2 в пакете Microsoft. Azure. Веб-задания. Расширения. DurableTask. github.com/Azure/azure-functions-durable-extension/issues/1282