Как грациозно завершить работу Quartz 3.0.x с ASP.NET Core 2.2 в IIS? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь изящно завершить задание Quartz, которое выполняется в IIS. Мой код выглядит следующим образом:

работа

    [DisallowConcurrentExecution]
    public class TestJob : IJob
    {
        private ILoggingService Logger { get; }
        private IApplicationLifetime ApplicationLifetime { get; }

        private static object lockHandle = new object();
        private static bool shouldExit = false;

        public TestJob(ILoggingService loggingService, IApplicationLifetime applicationLifetime)
        {
            Logger = loggingService;
            ApplicationLifetime = applicationLifetime;
        }

        public Task Execute(IJobExecutionContext context)
        {
            //TODO: does not seem work
            //context.CancellationToken.Register(() =>
            //{
            //    lock (lockHandle)
            //    {
            //        shouldExit = true;
            //    }
            //});

            return Task.Run(() =>
            {
                //TODO: check
                ApplicationLifetime.ApplicationStopping.Register(() =>
                {
                    lock (lockHandle)
                    {
                        shouldExit = true;
                    }
                });

                try
                {
                    for (int i = 0; i < 10; i ++)
                    {
                        lock (lockHandle)
                        {
                            if (shouldExit)
                            {
                                Logger.LogDebug($"TestJob detected that application is shutting down - exiting");
                                break;
                            }
                        }

                        Logger.LogDebug($"TestJob ran step {i+1}");
                        Thread.Sleep(3000);
                    }
                }
                catch (Exception exc)
                {
                    Logger.LogError(exc, "An error occurred during execution of scheduled job");
                }
            });
        }
    }

Startup.cs

protected void StartJobs(IApplicationBuilder app, IApplicationLifetime lifetime)
{
    var scheduler = app.ApplicationServices.GetService<IScheduler>();
    //TODO: use some config
    QuartzServicesUtilities.StartJob<TestJob>(scheduler, TimeSpan.FromSeconds(60));

    lifetime.ApplicationStarted.Register(() => scheduler.Start());
    lifetime.ApplicationStopping.Register(() => scheduler.Shutdown());
}

private static void ConfigureApplicationLifetime(ILoggingService logger, IApplicationLifetime lifetime)
{
    lifetime.ApplicationStopping.Register(() =>
    {
        logger.LogInfo(null, "Application is stopping...");
    });

    lifetime.ApplicationStopped.Register(() =>
    {
        logger.LogInfo(null, "Application stopped");
    });
}

Итак, я подключился к ApplicationStopping, чтобы иметь возможность корректно завершать работу Quartz. Однако, когда пул приложений IIS заканчивается, задания завершаются внезапно:

  • изменить что-то в web.config, чтобы вызвать остановку пула приложений
  • Пул приложений настроен так, чтобы разрешать до 90 секунд до окончания. Также допускается перекрытие
  • регистрация записей Application is stopping и немедленно Application stopped, таким образом, работа завершается внезапно

Я помню, что аналогичная реализация работала в ASP.NET с Quartz 2.x: заданиям Quartz было разрешено завершить свою работу при условии, что им удалось сделать это в период завершения работы пула приложений.

Вопрос: Как изящно завершить работу Quartz 3.0.x с ASP.NET Core 2.2 в IIS?

1 Ответ

0 голосов
/ 28 января 2019

Вы можете задать true для scheduler.Shutdown (), чтобы дождаться завершения заданий. Это должно задержать отключение пула до конца выполнения заданий.

lifetime.ApplicationStopping.Register(() => scheduler.Shutdown(true));

Подробнее об этом можно прочитать здесь .

...