Лучшая практика для закрытия экземпляра StatelessService в Service Fabric изнутри себя

Я работаю над сценарием ServiceFabric, в котором я запускаю экземпляр службы без сохранения состояния для выполнения некоторых задач. Я использую FabricClient.ServiceManager.CreateServiceAsync для создания экземпляра, и это работает как ожидалось.

Как только мои задачи будут выполнены, я хочу, чтобы служба, которую я породил, отключила себя, поэтому я использую FabricClient.ServiceManager.DeleteServiceAsync.

Служба завершает работу, как и ожидалось, однако мой отладчик останавливается в классе Program.Main в этой строке:

// Prevents this host process from terminating so services keep running.
Thread.Sleep(Timeout.Infinite);

Исключений нет, и я могу нажать "Продолжить", и после этого мое приложение запускается, как и ожидалось. Но я должен пропустить шаг, чтобы правильно закрыть свою службу. Есть ли способ "Best Practices", чтобы сделать это?

Я думал о том, чтобы мой сервис запросил другой сервис (например, хранителя), чтобы справиться с отключением, но мне это кажется слишком сложным.

Я бы предпочел, чтобы сама служба могла справиться с этим самостоятельно, если, конечно, это не является плохой практикой.

ОБНОВИТЬ:

Я переместил удаление службы в ManagerService для обработки его закрытия, но мой отладчик по-прежнему останавливается на Program.Main удаленной службы, как и раньше. Я также добавил скриншот (ниже).

Если я нажму "Продолжить", все будет работать как надо. Это потому, что отладчик все еще подключен и не понимает, что служба больше не работает под фабрикой? Может ли это быть проигнорировано и выпущено в производство?

введите описание изображения здесь

ОБНОВЛЕНИЕ 2

Я получаю много отзывов о том, что, поскольку у меня запущен отладчик, ожидается, что он будет зависать, если у меня больше не будет экземпляров этого конкретного сервиса, работающего на фабрике. Поскольку я получаю то же поведение, если я удаляю службу изнутри себя или из внешней службы, я хотел бы подумать о лучших методах для этого сценария...

В идеале лучше всего очистить службу, так как нет никаких зависимостей от внешней службы, она менее сложна и требует гораздо меньше кода для написания (и меньше ошибок).

Конечно, есть лучшая практика для этого, кроме необходимости вызывать FabricClient? Есть ли какое-то переопределение "Завершение работы"? Входит ли здесь CancellationToken?

3 ответа

Решение

Поведение, которое вы описываете, является ожидаемым (ваш отладчик, если вы запустили его в main, вероятно, все время находится на этой линии таймаута). Жизненный цикл хост-процесса не совпадает с жизненным циклом сервисов, размещенных в нем.

Когда процесс хоста пуст, Service Fabric немного ждет, прежде чем его отключить, поскольку хосты сервиса обычно не пусты в производственном процессе и пытаются избежать издержек, связанных с созданием и уничтожением процесса (что может замедлить последующее создание сервиса).

По умолчанию Service Fabric проверяет, является ли процесс пустым каждую минуту, а затем помечает его как закрывающий, затем выполняет очистку и закрывает пустые процессы каждые 10 минут или около того, чтобы вы могли видеть, что пустой процесс сохраняется примерно в течение 11 минут, если Вы точно выбрали время.

Вы создаете свой сервис извне. Имеет смысл также удалить сервис извне. Лично я бы отправил сообщение "хранителю", чтобы указать, что услуга завершена и может быть удалена.

Я видел, как это случилось со мной во время отладки сервисной структуры. Обычно я вижу такое поведение, когда мой отладчик подключен в течение длительного времени. Пока служба выключена, и вы можете убедиться, что она больше не существует после DeleteServiceAsync завершено, с использованием сайта Service Fabric Explorer, все должно быть в порядке.

Другие вопросы по тегам