LINUX.ORG.RU

Работа с systemd без sd_notify

 ,


1

2

Мы переводим наш flussonic на работу с systemd и я захотел воспользоваться его механизмом подтверждения того, что приложение запустилось.

Стандартный и официальный способ — использовать библиотеку systemd и использовать оттуда функцию sd_notify

Например для эрланга для этого есть библиотека https://github.com/systemd/erlang-sd_notify и похожее есть и для других платформ.

С этим подходом есть проблемы: 1) в любой современный язык втаскивать библиотеку на С — это задача, гораздо более неприятная, добавить библиотеку на самом языке. 2) в современных крутых платформах есть очень развитые подсистемы для работы с сокетом, а эта libsystemd делает чего-то, непойми что и не встраивается ни в libevent, ни в эрланговский event loop, ни в торнадо под питон.

Я решил сделать попроще, чего и вам советую:

https://gist.github.com/maxlapshin/01773f0fca706acdcb4acb77d91d78bb

ready() -> call(<<"READY=1">>).
reloading() ->call(<<"RELOADING=1">>).
stopping() -> call(<<"STOPPING=1">>).
watchdog() -> call(<<"WATCHDOG=1">>).


call(Call) ->
  case os:getenv("NOTIFY_SOCKET") of
    false ->
      {error, not_configured};
    Path ->
      case gen_udp:open(0, [local]) of
        {error, SocketError} ->
          {error, SocketError};
        {ok, Socket} ->
          Result = gen_udp:send(Socket, {local,Path}, 0, Call),
          gen_udp:close(Socket),
          Result
      end
  end.

в принципе вот всё, что нужно для работы с systemd. По ссылке более полный код на эрланге, его легко переписать за 10 минут на %LANG%

Понятно, что systemd не обещает сохранять api, но я бы вообще не стал рассматривать systemd как что-то очень продуманное и что не будет меняться следующие 10 лет. Всё равно всё будут перекраивать

★★★★★

Последнее исправление: max_lapshin (всего исправлений: 1)

эта libsystemd делает чего-то, непойми что и не встраивается ни в libevent, ни в эрланговский event loop, ни в торнадо под питон

А зачем тебе, простите, встраиваться в event loop ради того, чтобы открыть датаграммный сокет и отправить туда одну строчку?

Я решил сделать попроще

<эквивалентный синхронный код>

Как будто ты в своём коде встраиваешься в event loop и пользуешься «развитыми подсистемами для работы с сокетом».

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от intelfx

любая платформа, в которой используется evented работа с сокетами фактически не допускает другой работы.

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

max_lapshin ★★★★★
() автор топика

<code>

Мне просто любопытно - это такое заявление «недосуг мне нормально оформить пост, и так поймете»?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от tailgunner

нет, это просто я невнимателен. Поправил, спасибо

max_lapshin ★★★★★
() автор топика
Ответ на: комментарий от intelfx

Как будто ты в своём коде встраиваешься в event loop и пользуешься «развитыми подсистемами для работы с сокетом».

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

На одном ядре процессора таких зеленых тредов может обслуживаться много десятков тысяч одновременно.

Поэтому в случае с эрлангом встраивание в event loop происходит автоматически, в нём средствами самого языка заблокировать виртуальную машину невозможно: она не предоставит тебе таких средств.

max_lapshin ★★★★★
() автор топика
Ответ на: комментарий от max_lapshin

Ага, т. е. вот эта конструкция gen_udp:open создаёт синхронный, но неблокирующий сокет, который сам встраивается в event loop. Тогда понятно, да, ты прав.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от max_lapshin

Это пседосинхронный сокет.

Да, я это и имел в виду.

i-rinat, помнишь этот разговор про терминологию? Как там в результате условились называть такие примитивы?

intelfx ★★★★★
()

Тоже так делаю в личных мелких поделках.

anonymous
()

Но зачем встраиваться в event loop, если сообщение нужно отправить один раз? Ну заблокируется приложение на сколько-то наносекунд после старта, ну и черт бы с ним.

anonymous
()
Ответ на: комментарий от intelfx

Как там в результате условились называть такие примитивы?

Никак не условились, все остались при своих мнениях. Мне больше всего нравится «yielding call».

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

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

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

max_lapshin ★★★★★
() автор топика
Ответ на: комментарий от anonymous

1) watchdog надо слать регулярно

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

max_lapshin ★★★★★
() автор топика
Ответ на: комментарий от max_lapshin

Не вижу особой разницы. Всё равно вызов операции на сокете уступает выполнение другой сущности, если таковая есть. Нет особой разницы, один это процесс в системе или много. С точки зрения «логического» потока программы, он блокируется на операции, но при этом остальной мир продолжает двигаться.

i-rinat ★★★★★
()

Теперь понятно, чем занимаются на работе эрланговцы.

И за это платят в N раз больше, чем на %POPULARLANGNAME%?

anonymous
()
Ответ на: комментарий от max_lapshin

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

i-rinat ★★★★★
()
Ответ на: комментарий от tailgunner

Синхронный, потому что дожидается выполнения операции; неблокирующий, потому что не останавливает выполнение потока.

Прочитай выше. Мне не очень понятно, как называть такие примитивы. Псевдосинхронные? Псевдоблокирующие?

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

синхронный, но неблокирующий сокет

O_o

Прочитай выше.

Зачем читать выше (хотя я прочитал, конечно)? Сокет - системный объект, он не зависит от рантайма, который его создал. Бывают блокирущие сокеты и неблокирующие; о синхронных (и асинхронных, вероятно?) я не знаю.

Мне не очень понятно, как называть такие примитивы. Псевдосинхронные? Псевдоблокирующие?

Не знаю. Но не надо придумывать новые имена существующим вещам.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Бывают блокирущие сокеты и неблокирующие

В openresty сокеты блокирующие или не блокирующие?

i-rinat ★★★★★
()
Ответ на: комментарий от tailgunner

да вот тут как раз такая ситуация, что задница есть, а слова нет.

Всем этим явлениям нет хороших терминов. Как назвать то, что в ноде фактически является тем же, что в эрланге называется процессом?

max_lapshin ★★★★★
() автор топика
Ответ на: комментарий от max_lapshin

Как назвать то, что в ноде фактически является тем же, что в эрланге называется процессом?

В Node.js появились легкие процессы в стиле Erlang? Не знал. Web workers вроде не похожи.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.