Всякий раз, когда вам нужно изменить поведение внутри Hangfire, вы должны написать JobFilter .
Этот класс может реализовывать различные интерфейсы, но в вашем случае вы, вероятно, могли бы реализовать IClientFilter
и отметьте OnCreating()
, если задание должно быть создано, или внедрите IElectStateFilter
и отметьте OnStateElection()
, если задание должно быть поставлено в очередь.
Помните, что уже есть куча других фильтров задания и чтоони выполняются в определенном порядке, заданном целочисленным значением в свойстве Order
. Чтобы убедиться, что ваш фильтр будет одним из последних, установите для этого значение, возможно, значение int.MaxValue
.
Чтобы применить этот фильтр задания к своей работе, вы можете либо добавить атрибут к методу или классу, либо, если он долженбыть выполненным для каждой работы, которую вы можете добавить в глобальный список с помощью GlobalJobFilters.Filters.Add()
при запуске.
Если вы находитесь в одном из методов фильтрации, у каждого из них есть свойство context
, которое имеетдоступ к API мониторинга через свойство Storage
:
var monitor = context.Storage.GetMonitoringApi();
var jobDetails = monitor.JobDetails(context.BackgroundJob.Id);
foreach (var kvp in jobDetails.Properties)
{
Trace.WriteLine($"{kvp.Key => kvp.Value}");
}
foreach (var entry in jobDetails.History.OrderBy(e => e.CreatedAt))
{
Trace.WriteLine($"{entry.StateName} ({entry.CreatedAt}): {Reason}");
foreach (var kvp in entry.Data)
{
Trace.WriteLine($" {kvp.Key} => {kvp.Value}");
}
}
В настоящее время я не могу проверить, что они содержат в случае вновь созданного повторяющегося задания, но если вы посмотрите на него с помощью отладчикаВы должны найти некоторую информацию о повторяющейся работе. Один простой способ проверить это - взглянуть на панель управления Hangfire. Если вы откроете страницу сведений о задании и найдете что-нибудь, связанное с повторяющимся заданием, чем это доступно через API мониторинга, все веб-страницы Hangfire используют этот API для получения своего контента.
Просто копните немного глубже инашел точки для извлечения всей информации из повторяющегося задания по заданному идентификатору задания:
var monitor = context.Storage.GetMonitoringApi();
var jobDetails = monitor.JobDetails(context.BackgroundJob.Id);
if(jobDetails.Properties.TryGetValue("RecurringJobId", out string recurringId))
{
var values = context.Connection.GetAllEntriesFromHash($"recurring-job:{recurringId}");
foreach (var kvp in values)
{
Trace.WriteLine($"{kvp.Key} => {kvp.Value}");
}
}
Кроме того, состояние Enqueued повторяющегося задания всегда имеет в качестве причины текст Triggered by recurring job scheduler
, который можно использовать какфильтр как это:
public void OnStateElection(ElectStateContext context)
{
switch (context.CandidateState)
{
case EnqueuedState enqueued when enqueued.Reason == "Triggered by recurring job scheduler":
Trace.WriteLine($"Was triggered by job scheduler.");
// Skip all jobs of job scheduler
context.CandidateState = new SucceededState(null, 0, 0);
break;
}
}