Улучшение сервиса для остановки «по требованию»

  1. часть: создание сервиса
  2. часть: вы читаете это прямо сейчас
  3. часть: обновление для Интернета
  4. часть: добавление SSE
  5. часть: простая функциональность внешнего интерфейса javascript
  6. часть: frontend - backend коммуникация
  7. часть: логирование на стороне сервера
  8. часть: запустить все в докере
  9. часть: добавление контейнера базы данных
  10. часть: база данных - служебная связь

Дополнение 1: функции, методы, указатели и интерфейсы
Дополнение 2: связь через веб-сокеты
Дополнение 3: связь через сокеты

Что значит «правильный путь»?

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

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

Это означает: все, что происходит в вашем рабочем коде, не будет зашифровано, когда кто-то остановит вашу службу. Конечно, есть много способов, как это сделать. Это мой стиль работы.

Обновите код

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

Добавить переменные

Эти две переменные мы назовем serviceIsRunning и programIsRunning. Начнем с добавления этих двух переменных чуть ниже раздела импорта. Добавим третью переменную типа sync.Mutex. Эта переменная берет на себя ответственность за синхронизацию при записи или чтении в / из этих двух логических переменных (когда две строки кода хотят обновить переменную serviceIsRunning в одно и то же время, мьютекс допускает только одну строка кода, чтобы внести изменение, и затем пригласите вторую строку кода внести ее изменение).

В этом конкретном примере мы не будем записывать в одну переменную из двух разных разделов кода, поэтому в этом sync.Mutex нет необходимости сейчас, но мы будем его использовать.

Как видите, все три переменные подчеркнуты красным. Причина снова та же: мы нигде не используем эти переменные.

Обновите методы

Сначала мы начнем с serviceIsRunning.

Обновите Start() метод приведенным ниже кодом. Первоначально для переменной serviceIsRunning установлено значение false. После запуска службы мы установили для нее значение true. Перед установкой мы блокируем эту serviceIsRunning переменную с помощью writingSync.Lock(), поэтому любая другая будущая строка в программе (которая хочет записать в ту же переменную) должна ждать, пока эта writingSync разблокирует обратно нашу serviceIsRunning переменную. Теперь, когда наша служба запускается, наша переменная serviceIsRunning установлена ​​правильно.

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

Пришло время поиграть с переменной programIsRunning. Переходим к run() методу. Сначала мы хотим убедиться, что наш производственный код будет работать только в том случае, если служба уже запущена. Смотрите код ниже, ничего особенного. Добавление одного условия: производственный код выполняется, только если переменная serviceIsRunning истинна.

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

Обновить производственный код

Чтобы увидеть эффект в работе, обновите метод time.Sleep(), чтобы он подождал 2 секунды (вы можете попробовать 5 секунд, чтобы лучше увидеть эффект).

Мы снова играем с этой переменной мьютекса и впервые с переменной programIsRunning. Код ниже показывает изменения.

Выполнение этого кода занимает около двух секунд. Вначале мы устанавливаем programIsRunning на true (так что везде в нашем коде мы можем проверить, запущена ли эта программа). И после завершения этого цикла мы снова устанавливаем для этой переменной programIsRunning значение false.

После того, как все это будет сделано, вы можете проверить, работает ли программа. И запускается, но… все равно никакого эффекта.

Окончательная точная настройка

Вернемся к нашему Stop() методу. Обновите код новым циклом. Этот новый цикл просто ожидает, пока переменная programIsRunning не станет false (что означает: он ждет, пока рабочий код завершит себя).

И только тогда цикл завершится Stop() методом.

Финальный тест

Запустите код сейчас (если вы не видите эффекта, увеличьте time.Sleep() в run() методе до 5 секунд).

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

Например: если вы увеличите время сна в run() методе до 10 секунд, вы увидите намного больше Medium service stopping ... строк. Конечно, это зависит от того, когда вы остановите программу.

Резюме

Прочитав эту статью, вы узнаете, как…

  • Сделайте так, чтобы ваша служба работала и завершалась должным образом
  • знать в каждой части кода, каково состояние службы