LINUX.ORG.RU
ФорумTalks

Немного Марсианской Логики

 


3

2

Усаживайтесь поудобнее детишки, сейчас дядя Кирк расскажет вам сказку. Как вы думаете, что делает опция Requires= в юнит-файле systemd? Думаете она определяет жесткую зависимость одного сервиса от другого, загружая их в правильном порядке? О нет, детишки, вы жестоко ошибаетесь:

Note that requirement dependencies do not influence the order in which services are started or stopped.

Именно так, для определения порядка нужно использовать After=. И вот я сижу и пытаюсь представить, какой извращенный use-case пришел этим людям в их гойловы и кто вообще выпустил разработчиков из зоопарка.

★☆

Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: Все правильно сделано от gistart

Поэтому пусть они стартуют вместе, а клиент, не будь дурак, пусть проверяет

И если что рапортует «DB failure» ага! И да клиент _всегда_ стартует после сервиса.

ioway
()

Но всё-таки когда для указания факта «сервис X зависит от сервиса Y» нужно указывать и Requires, и After - это, конечно, разруха в голове разрабов systemd. И в головах тех, кто считает это нормальным - тоже разруха.

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

Про постгрес

Там есть такая штука, как autovacuum.

Там есть такая штука как VACUUM, физически удаляющая записи, помеченные как «удаленные», вот давно не тыкал сырцы, но еще она должна была производить дефрагментацию. При ее работе будут лаги при доступе к БД, но база будет работать. Убивание по -9 на базу не влияет. AVTOVACUUM - то же самое но запускается самим пострелом по трешолду, без участия кронов и т.д. Запускается очень умно. Убивание родительского процесса постгреса может привести к разрушению БД, но знаешь, если врезать человеку топором по башке - он тоже «ляжет», вот только делать это сильно не рекомендуется. Так что тут сустемд к постгресу (с его то набором ОС) вообще никуда не упал.

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

Убивание родительского процесса постгреса может привести к разрушению БД

Перечитай ещё раз то, что я написал.

Обратный порядок запуска? Ты точно понимаешь о чем мы говорим?

Прекрасно понимаю. А ты, судя по всему, не очень.

т. е. в некоторых случаях приходится использовать Requires= в паре с Before=

Нет.

Выше был приведён пример.

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

Перечитай ещё раз то, что я написал.

Перечитал и сильно усомнился в твоем понимании процесса.

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

Если приблуда не работает без постгреса, с чего бы ей запускаться раньше него?

зато какая быстрая загрузка!

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

Я пять постов назад сказал, что мы рассматриваем гипотетическую ситуацию, в которой postgres и его autovacuum — разные юниты.

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

мы рассматриваем гипотетическую ситуацию

Ок, тут мой косяк. Но тем не менее зависимость и последовательность - две взаимоисключающие сущности. Просто кто-то «ниасилил» зависимости.

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

Но тем не менее зависимость и последовательность - две взаимоисключающие сущности.

Чего-чего?

И да, я привёл конкретный пример, когда Requires= нужно использовать в паре с Before=, а не с After=. Да, он гипотетический, но вполне реальный. У тебя есть возражения?

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

То есть взаимозависимых демонов ты не писал?

Писал. Поэтому и упомянул, что сабж ТС - головняк и недоработка. Кривовато.

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

И да, я привёл конкретный пример,

Нет. Ты привел пример UB.

Да, он гипотетический

Он неверный.

Чего-чего?

Они взаимоопределяющие и одновременно использоваться не могут.

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

Но всё-таки когда для указания факта «сервис X зависит от сервиса Y» нужно указывать и Requires, и After - это, конечно, разруха в голове разрабов systemd.

Before=, After=

A space-separated list of unit names. Configures ordering dependencies between units. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up. Note that this setting is independent of and orthogonal to the requirement dependencies as configured by Requires=. It is a common pattern to include a unit name in both the After= and Requires= option, in which case the unit listed will be started before the unit that is configured with these options.

Разруха у тех кто документацию не читал.

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

Разруха у тех кто документацию не читал.

У тебя очень хреново с построением архитектуры. Объясню «на пальцах». Если ты хочешь ссать - тебе нужен туалет. Он тебе нужен заранее и раньше чем он появится - тебе некуда сходить. Так вот, когда ты покупаешь жилье - туалет тебе _уже_ нужен, чисто физиологически. И тебе будет весьма тяжко, если тебе приспичит, а рабочие скажут «Чувак, мы начали строить туалет, когда ты сюда приехал и он еще не готов», или «Чувак, прораб сказал, строить туалет только если тебе приспичит». Вот ты сейчас пытаешься объяснить логичность такого поведения, школьник пытается объяснить, что это логично и отсутствие в доме туалета - твои проблемы на «Чиста, гиппатетических, Уася, примерах».

Я бы на месте вас обоих всерьез задумался о карьере PHP-фрилансеров, пока вы не накосячили до уровня «продам почку».

ioway
()
Ответ на: комментарий от Shadow

Ви таки постгрес дискредитируете или шо?

Это гипотетический пример в гипотетическом линуксе с гипотетическим предназначением. Вобщем без его дилера нам не понять.

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

Если ты хочешь ссать - тебе нужен туалет.

Увожаемый, когда поссышь тогда и приходи, пообщаемся нормально. А свои сортирные темы оставь при себе.

Deleted
()
Ответ на: комментарий от ioway

Аналогии не нужны. Ты лучше скажи, как бы ты сделал. Я лично представлял себе, что в случае упоминания After= или Before= директива Requires= попросту не нужна, она подразумевается. И я весь топик пытаюсь понять, зачем она нужна в случае наличия After или Before. В доке написано: ортогонально. Я не пойму. Ты понял? Или так же считаешь, что она избыточна?

Вот что пусть объяснят сведующие люди

(Как я понимаю, Wants= и Requires= взаимоисключающие. Могут ли быть After (Before) совместно с Wants ?)

Deleted
()
Ответ на: комментарий от ioway

Во-первых, уважаемый.

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

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

Ты лучше скажи, как бы ты сделал.

Я бы оставил директиву require и дал админу инструменты для самоопределения. Например, любой системный администратор (ну если за последние 16 лет ничего не поменялось), знает, что ему нужно для того чтобы работал некий сервис. Вот давай на сложном примере, стоковый трэйдинг, у тебя есть «медленная база» - постгрес, и быстрая база - допустим аероспайк. В медленной базе ты хранишь метаданные, в быстрой - текущие цены (они меняются как ураган), у тебя есть два сервиса, один встречает Fix-поток с новыми ценами и пишет их в аероспайк, также у тебя есть REST сервис предоставляющий консолидированные данные аналитикам через nginx.
Давай так,

A - аэроспайк
P - постгрес
N - nginx
SA - твой сервис который пишет в аероспайк
SP - твой сервис предоставляющий данные через nginx

(извини, но я буду сказать «нужен» вместо required)

SA нужен старт аэроспайк
SP нужен старт постгреса, аэроспайка и nginx

При этой семантике

А,P и N стартуют одновременно, при старте A запускается SА и начинает обновлять цены.
При запуске N и P, запускается SP.

Простая семантика в которой достаточно сказать

SA require A
SP require A,P,N

Все! Точка!

Просто Поццеринг - туп до непроходимости.

ioway
()
Ответ на: комментарий от Deleted

И я весь топик пытаюсь понять, зачем она нужна в случае наличия After или Before. В доке написано: ортогонально.

Допустим у тебя есть vpn. Его надо запускать только после networkmanager-online, systemd-networkd.service + resolved (емнип, online для него пока не поддерживается), network.service и т.п. Что именно у пользователя используется ты не знаешь, может даже что-то своё. Знаешь, что если кто-то из них запущен, то стартовать надо после него.

Ты пишешь After=networkmanager-online.service, After=network.service и т.п. Проблема решена. Если я хочу сменить network.service на systemd-networkd.service, я могу не вносить никаких изменений в сервис vpn.

Альтернатива, клепать ещё один таргет, чуть ниже network-online.target, на который ставить зависимость для vpn. Что лучше, вопрос спорный, но в systemd возможны оба варианта.

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

Как я понимаю, Wants= и Requires= взаимоисключающие. Могут ли быть After (Before) совместно с Wants ?

Wants - слабая версия requires. Если a requires b, и b при этом не запустился, то a тоже не запустится. Если a wants b, и b при этом не запустился, то a запустится и продолжит работу.

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

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

ioway
()
Ответ на: комментарий от Ivan_qrt

А если ситуация будет отличаться, ты напишешь новый инит?

Отличаться от «если это стартовало»? Ты точно не потерял нить разговора?

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

Отличаться от «если это стартовало»?

Как в твоём «мозгу» зарождаются такие интерпретации?

Отличаться от приведённого тобой графа зависимостей.

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

Если a requires b, и b при этом не запустился, то a тоже не запустится

Note that requirement dependencies do not influence the order in which services are started or stopped.

Так что запустится.

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

Да, postgres requires autovacuum, но postgres before autovacuum, а не after.

Вот это довольно мерзкая хрень, потому что:

  • Порождает чудесный ад, о котором я написал в посте
  • Порождает чудесный race condition (который в случае с postgres не особо важен, конечно)
  • Не дает особых преимуществ, потому что эту проблему можно решить не создавая неочевидностей в конфигурации
kirk_johnson ★☆
() автор топика
Последнее исправление: kirk_johnson (всего исправлений: 2)
Ответ на: комментарий от Ivan_qrt

Как в твоём «мозгу» зарождаются такие интерпретации?

Ну а что если, «стаивало» это просто автокоррекция? От СТАРОВАТО, ты не знал что она иногда срабатывает, ути-пути, какие мы юные.

ioway
()
Ответ на: комментарий от Ivan_qrt

Допустим у тебя есть vpn. Его надо запускать только после networkmanager-online, systemd-networkd.service + resolved (емнип, online для него пока не поддерживается), network.service и т.п. Что именно у пользователя используется ты не знаешь, может даже что-то своё. Знаешь, что если кто-то из них запущен, то стартовать надо после него.

depend() {
        need localmount net
        use dns
        after bootmisc
}

Видишь, как просто решается эта проблема в OpenRC?

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

Другой аргументации у Вас нет?

Если ты не способен разложить суперсложную сетку зависимостей - НЕТ! Ты тупо слил.

ioway
()
Ответ на: комментарий от Ivan_qrt

Допустим у тебя есть vpn.

Как в этом случае применяется Requires= ?

Wants - слабая версия requires

Это я знаю. Можно ли делать «Wants=b.service\nAfter=b.service» по аналогии с «Requires=b.service\nAfter=b.service» ?

Всеравно назначение Requires при наличии After или Before мне непонятно. Имхо, это оверхед и дублирование. Не могу придумать пример, работа которго отличается при «After=b\nRequieres=b» от «After=b»

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

ну для таких кейсов когда «ложный» запуск точно не нужен какраз есть Before

другй подход требовал бы целых 6 директив:

RequiresBefore

RequiresSimultaneously

RequiresAfter

WantsBefore

WantsSimultaneously

WantsAfter

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

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

другй подход требовал бы целых 6 директив:

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

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

но не на долго

Объясняю «не на долго» - ебут сначала девопс, потом ебут девелоперов,потом приходят ребята из секурити и объясняют всем какие они важные пацаны, потом как бы чтобы «Бабки как-то надо вернуть», Им объясняют что в рамках контракта они рискуют выйти за рамки закона

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

ну не yaml и не xml же, а другого common формата я не знаю например. да можно (и возможно нужно) было свой накатать

Deleted
()
Ответ на: комментарий от tailgunner
$ cat /etc/systemd/system/testA.service
[Unit]
Description=TestA service.
Requires=testB.service

[Service]
Type=simple

ExecStart=/usr/bin/echo TestA start.
ExecStop=/usr/bin/echo TestA stop.

[Install]
WantedBy=multi-user.target


$ cat /etc/systemd/system/testB.service
[Unit]
Description=TestB service.
Requires=testA.service

[Service]
Type=simple

ExecStart=/usr/bin/false
ExecStop=echo TestB stop.

[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl start testA.service
# journalctl -e
systemd[1]: Started TestB service..
systemd[1]: Starting TestB service....
systemd[1]: Started TestA service..
systemd[1]: Starting TestA service....
echo[16527]: TestA start.
systemd[1]: testB.service: main process exited, code=exited, status=1/FAILURE
systemd[1]: Unit testB.service entered failed state.
systemd[1]: testB.service failed.
echo[16535]: TestA stop.
Ivan_qrt ★★★★★
()
Ответ на: комментарий от Deleted

да можно (и возможно нужно) было свой накатать

Определенно нужно было - если бы поцеринг не был тупым Си-кодером, он бы и накатал. Да хотя бы:

Requires = foo.service; parstart=no
tailgunner ★★★★★
()
Ответ на: комментарий от Ivan_qrt

echo[16527]: TestA start.

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

Deleted
()
Ответ на: комментарий от Ivan_qrt

Ага. У тебя модули зависят друг от друга, и когда оба запущены, смерть одного ведет к смерти другого. Но _ПОРЯДОК_ загрузки не определяется.

kirk_johnson ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.