Сервер Hangfire пытается обработать задание из другой очереди - PullRequest
0 голосов
/ 25 апреля 2018

Я хотел бы спросить, есть ли способ определить, что сервер HangFire не должен обрабатывать повторяющиеся задания?

Есть два приложения (служба Windows и веб-приложение), которые используют HangFire для запуска фоназаданий, поэтому есть два сервера зависания (очереди определены правильно).

Служба создает только повторяющиеся задания и использует очередь «по умолчанию».Веб-приложение создает запущенные задания и использует другую очередь (например, web_app_queue).

Кажется, что сервер HangFire, созданный веб-приложением, пытается планировать / обрабатывать повторяющиеся задания, хотя они определены длядругая очередь, но сервер HangFire веб-приложения не имеет доступа к необходимой сборке, доступной для службы Windows.

Сервер HangFire веб-приложения:

var backgroundJobServer = new BackgroundJobServer(new BackgroundJobServerOptions { Queues = new[] { "web_app_queue" } });

Задание HangFire веб-приложения:

var client = new BackgroundJobClient();
var state = new EnqueuedState("web_app_queue");
var jobId = client.Create(methodCall, state);

Сервер Windows службы HangFire:

var server = new BackgroundJobServer();

Задание HangFire службы Windows:

private static void AddRecurringJob<T>(string cronExpression) where T : IJob
{
    RecurringJob.AddOrUpdate<T>(job => job.Execute(), cronExpression, TimeZoneInfo.Local);
}

Имя очереди не определено для сервера и заданий HangFire службы Windows, поэтомуприменяется очередь по умолчанию («default»).

Сообщение об исключении и подробности здесь:

message="Recurring job ... can not be scheduled due to job load exception."

detail="Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details. 
---> System.IO.FileNotFoundException: Could not load file or assembly 'XXX.YYY, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.;   
    at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type);   
    at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark&amp; stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName);   
    at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase);   
    at Hangfire.Storage.InvocationData.Deserialize();   
    --- End of inner exception stack trace 
    at Hangfire.Storage.InvocationData.Deserialize();  
    at Hangfire.Server.RecurringJobScheduler.TryScheduleJob(JobStorage storage, IStorageConnection connection, String recurringJobId, IReadOnlyDictionary`2 recurringJob);   
    at Hangfire.Server.RecurringJobScheduler.Execute(BackgroundProcessContext context)"

1 Ответ

0 голосов
/ 27 апреля 2018

Я нашел решение для моей проблемы здесь: https://github.com/HangfireIO/Hangfire/issues/775
Таким образом, можно создать сервер HangFire (используя класс BackgroundProcessingServer) и определить, какие процессы могут обрабатываться этим сервером.

Таким образом, ясмог определить, что сервер моего веб-приложения HangFire должен обрабатывать только запущенные процессы

Пример ниже:

    int workerCount = Environment.ProcessorCount * 5;
    string queueName = "web_app_queue";

    List<IBackgroundProcess> processes = GetProcessesForBackgroundServer(queueName, workerCount);
    var backgroundJobServer = new BackgroundProcessingServer(JobStorage.Current, processes, new Dictionary<string, object> { { "Queues", new string[] { queueName } }, { "WorkerCount", workerCount } });


    private List<IBackgroundProcess> GetProcessesForBackgroundServer(string queueName, int workerCount)
    {
        var processes = new List<IBackgroundProcess>();

        for (var i = 0; i < workerCount; i++)
        {
            processes.Add(new Worker(queueName)); //only fire-and-forgot jobs will be processed by this server (important processes ServerHeartbeat, ServerWatchdog are included automatically by BackgroundProcessingServer)
        };

        return processes;
    }
...