#.net #async-await #task-parallel-library #quartz.net
#.net #асинхронное ожидание #задача-параллельная-библиотека #quartz.net
Вопрос:
У меня есть задание quartz, которое выполняется периодически, и во время выполнения я бы отправил запрос api rest через HttpClient. В настоящее время, если «вызов» rest api не удался (например, неверный код состояния запроса 400), он будет «повторно отправлять» один и тот же вызов api, например, 2-4 раза. Это поведение не является «правильным», все, что я хочу, это записать результат вызова rest api, поскольку я бы не хотел, чтобы запрос postasync выполнялся после первоначального времени запуска.
- Итак, это в основном «псевдокод», я просто создаю кучу отчетов с помощью задания quartz, а затем отправляю их.
- Проблема возникает, когда происходит сбой createreport, каким-то образом запрос будет «повторно отправлен» (я регистрируюсь из функции createReport после ожидания, и я вижу, что запрос повторно / ответ получен снова)
- Я довольно новичок в этом, поэтому я не уверен, что механизм повторной попытки уже встроен в async await или сам quartz.
class Job : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var tasks = Enumerable.Range(0, count).Select(index => CreateReport(index));
try
{
await Task.WhenAll(tasks);
}
catch { }
}
public static async Task CreateReport(int index)
{
var response = await ReportApi.PostAsync($"api/createReport/...", null);
}
}
Комментарии:
1. покажите свой код. quartz не будет автоматически запускать задачу снова из-за сбоя.
2. Используйте библиотеку, подобную Polly, для стратегий повторных попыток. github.com/App-vNext/Polly
3. Моя проблема в том, что он «повторяет попытку» сам по себе, я не хочу, чтобы он повторял попытку, как polly исправит то, что у меня сейчас есть?
Ответ №1:
В идеале в этом случае вы бы смоделировали свою модель более похожей на обмен сообщениями. У вас может быть одно задание, но вы можете создать триггер для каждого отчета, который вызывает задание, у вас может быть «идентификатор отчета / идентификатор пользователя / etc» в качестве параметра для запуска сопоставления данных задания. Таким образом, проблемы будут затрагивать только один отчет за раз.
Теперь, если ваша работа завершится неудачей, она будет повторена по умолчанию. Вы можете запретить это, используя логику try-catch вокруг вашей логики и в случае выброса ошибки JobExecutionException
, которая позволяет вам устанавливать логические условия с помощью своих свойств, например UnscheduleFiringTrigger
, что позволяет ему прекратить повторную попытку — но это для одноразового триггера, рассматриваемый триггер больше никогда не сработает во время выполнения schduler.
Как правило, я бы посоветовал для управления состоянием (был ли сгенерирован отчет) во внешнем источнике, таком как база данных. Затем в триггере проверьте, какое действие правильное. Также, как предложено в комментариях, библиотека повторных попыток может позволить выполнять более детализированные действия.