#c# #azure #azure-functions #azure-durable-functions
#c# #azure #azure-функции #azure-durable-функции
Вопрос:
Я хочу иметь очень легкий подход, при котором я предоставляю конечную точку HTTP (триггер), которая в некоторой степени предоставляет доступ к долговременному объекту (субъекту) и заставляет субъекта выполнять работу на регулярной основе.
Логика в моем HTTP-триггере выглядит следующим образом:
- Проверьте, существует ли объект с uid уже
- Если нет, подайте сигнал объекту и запустите
InitializeMonitoringAsync
метод для субъекта - Если да, вызовите состояние объекта для субъекта и верните некоторые значения
- После инициализации субъект (долговременная сущность) должен часто вызывать
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