К сожалению такой вариант для YC не приемлем, тк в случае пересоздания какого-то хоста у кластера его ID (то есть адрес хоста) будет изменен, что потребует изменения настроек в строке подключения.
Я указываю все хосты. Приходится менять строку подключения. Страдаю.
Я не утверждаю, что опция target_session_attrs=read-write не даёт никакого эффекта: эффект есть, но природа у него другая.
В данном случае у поставщика (Яндекс облака), есть три варианта подключения к PostgreSQL-кластеру:
указать все хосты в строке подключения и target_session_attrs - рекомендуемый способ;
использовать FQDN для PRIMARY - зависит от времени обновления DNS, не рекомендуется из-за отсутсвия гарантий на время из-за DNS-кэшей;
использовать FQDN для наименее отстаюущей реплики - так же зависит от времени обновления DNS.
Комбинация FQDN для PRIMARY и target_session_attrs=read-write работать будет, но есть нюансы:
время переключения увеличивается за счет DNS-кэшей (они зависят от TTL DNS записи, настроек операционной системы приложения, реализации самого приложения);
клиент в случае failover на некоторое время вообще не видит никакого хоста кластера (адрес резолвится в мёртый хост);
поведение может сильно отличаться в зависимости от используемого в разработке стэка;
вы игнорируете явное предупреждение поставщика и делаете на свой страх и риск (используйте подключение с помощью особого FQDN хоста-мастера только для процессов, которые допускают недоступность базы данных на запись продолжительностью до 10 минут);
вы используете FQDN для PRIMARY не по назначению на свой страх и риск.
С моей колокольни - 20-30 секунд в данном эксперименте это довольно много (речь же идёт не про failover, а про switchover - прибить лопатой хост в облаке довольно трудно и, скорее всего, вы просто переключаете PRIMARY в кластере).
То что вы видете ожидаемый результат в рамках своего эксперимента не значит, что эксперимент проведён корректно.
При подключении к этому FQDN разрешено выполнять операции чтения и записи.
Примечание
Используйте подключение с помощью особого FQDN хоста-мастера только для процессов, которые допускают недоступность базы данных на запись продолжительностью до 10 минут.
C git'ом кстати тоже есть проблема, он хорошо подходит для сорцов, а вот что делать с гигабайтными текстурами или файлами модели по 100мб, или луашником/json'ом уровня размером под 20-30 мб текста? Тут либо держишь 2 cvs - одну для сорцов, вторую для контента, либо пишешь своё решение.
Большие файлы стало можно использовать после появления Git LFS.
Для совсем мелких проектов подходит почти всё, что угодно.
Проблемы начинаются когда увеличивается количество хотелок:
Хочется, чтобы в выводе сборки можно было узнать, какие тесты попадали и как?
Хочется иметь хоть какую-то статистику по тестам (тут с ностальгией вспоминаю TeamCity);
Хочется иметь разбивку по этам сборки, чтобы не нужно было искать ошибку в одном гигантском логе;
Хочется иметь нотификации авторам о падении тестов;
Хочется иметь интеграцию с системой контроля версий;
Хочется иметь возможность как-то управлять секретами;
Хочется иметь возможность делать цепочки сборок;
И т.д. и т.п.
При этом основные проблемы визуализации возникают в негативном сценарии: пока всё работает, оно никому не интересно. А вот возможность по выводу понять, что и где пошло не так, очень полезна.
Проблему безопасности можно частично решить через вынос общих запчастей в отдельную "доверенную" Jenkins Shared Library. Тогда на её код в src не будут распространяться ограничения песочницы, хотя на vars - всё ещё будут.
На счет плагинов я с Вами согланен: в Jenkins безумное количество legacy и очень разное качество кода от плагина к плагину.
Ну и отдельная проблема в том, что там модульность доведена до абсурда: обычно функционал затрагивает сразу несколько плагинов и не всегда очевидно, какой именно за какую часть фичи отвечает.
Если сборка совсем типовая, то всю эту сложность можно попытаться спрятать, но что-то мне подсказывает, что под капотом standardDeclarativePipelineTemplate творится жесть.
Ну и декларативный pipeline в Jenkins то еще поделие: это де-факто инструкция императивного pipeline, то есть всё равно нельзя сказать, что сделает pipeline не выполнив его.
Из-за этого, в частности:
вечно поломанная визуализация сборки;
объявления параметров и опций в pipeline влияет на следующую, а не на текущую сборку.
С моей точки зрения, SQL СУБД должна соответствовать хоть одному SQL-стандарту. Должен быть не только похожий синтаксис, но и поведение.
К примеру, запрос:
UPDATE foo SET a = b, b = a WHERE id = 42
должен внутри выражений брать значения исходного кортежа, то есть поменять значения полей a и bместами. В MySQL же в обе колонки попадёт исходное значение b.
Про особенное виденье уровней изоляции транзакций уже было выше.
Все эти особенности в MySQL документированы и переведены в категорию фичей, но от этого как-то не легче.
Вы не представляете масштаб проблемы: распил проекта на маленькие модули требует годы.
Даже если предположить, что проект волшебным образом распадётся на сотни маленьких слабо связанных модулей, то их всё равно нужно будет чем-то собирать.
К тому же сокращение времени на итерацию в CI делает рефакторинг заметно комфортнее.
Я так и не смог понять, как подружить IDE и Bazel...
Собственно из-за этого и пошли по пути, когда BUILD-файлы генерируются на базе исходного кода и go.mod-файлов, максимально повторяя go build-сборку.
На машинках разработчиков Bazel используется только для создания генерируемых .go-файлов, которые потом раскладываются в рабочей копии. В результате для большинства, кроме этого вызова генератора, Bazel никак не используется.
Эта схема оказалась на удивление удачной:
разработчикам не нужно воевать с Bazel;
IDE работает как работало;
генераторы получают возможность генерировать зависящие от компиляции данные (в нашем случае mock-и);
если нужно, разработчик может использовать Bazel как для сборки, так и для запроса зависимостей через bazel query.
40 минут это был средний результат инкрементальной сборки на 7-ми машинках в параллель. По нашим прикидкам, на одной машинке с холодным кэшем должно было быть часов 15. В основном это время уходило на линковку тестовых бинарей: каждый пакет с тестами собирается в отдельный исполняемый файл и на это уходит чудовищное количество времени и дискового пространства. На втором месте собственно исполнение тестов.
В комментариях к коду и описании коммитов самая ценная информация - ответы на вопросы "зачем это было сделано?" и "почему было сделало именно так?"
В лучшем случае эту информацию можно достать из тикета, в худшем - только из головы разработчика.
Я указываю все хосты. Приходится менять строку подключения. Страдаю.
К счастью хосты сами свои имена не меняют.
Я не утверждаю, что опция
target_session_attrs=read-writeне даёт никакого эффекта: эффект есть, но природа у него другая.В данном случае у поставщика (Яндекс облака), есть три варианта подключения к PostgreSQL-кластеру:
указать все хосты в строке подключения и
target_session_attrs- рекомендуемый способ;использовать FQDN для PRIMARY - зависит от времени обновления DNS, не рекомендуется из-за отсутсвия гарантий на время из-за DNS-кэшей;
использовать FQDN для наименее отстаюущей реплики - так же зависит от времени обновления DNS.
Комбинация FQDN для PRIMARY и
target_session_attrs=read-writeработать будет, но есть нюансы:время переключения увеличивается за счет DNS-кэшей (они зависят от TTL DNS записи, настроек операционной системы приложения, реализации самого приложения);
клиент в случае failover на некоторое время вообще не видит никакого хоста кластера (адрес резолвится в мёртый хост);
поведение может сильно отличаться в зависимости от используемого в разработке стэка;
вы игнорируете явное предупреждение поставщика и делаете на свой страх и риск (используйте подключение с помощью особого FQDN хоста-мастера только для процессов, которые допускают недоступность базы данных на запись продолжительностью до 10 минут);
вы используете FQDN для PRIMARY не по назначению на свой страх и риск.
С моей колокольни - 20-30 секунд в данном эксперименте это довольно много (речь же идёт не про failover, а про switchover - прибить лопатой хост в облаке довольно трудно и, скорее всего, вы просто переключаете PRIMARY в кластере).
То что вы видете ожидаемый результат в рамках своего эксперимента не значит, что эксперимент проведён корректно.
Нет. С
target_session_attrs=anyникто не мешает использовать из пула уже имеющиеся подключение по старому адресу.Но до переключения FQDN клиент PRIMARY не увидит. При этом никто не гарантирует, что изменение DNS записи быстро доедет до приложения.
У вас наслаивается два эффекта:
необходимость создать новое подключение, так как старое не удовлетворяет запрошенному
target_session_attrs=read-write;изменение адреса, в который резолвится FQDN имя.
И это создаёт иллюзию, что оно работает правильно. Но время переключения сильно зависит от кэша DNS, на который в таких вещах лучше не полагаться.
По хорошему, в строке подключения вместо этого FQDN должны быть указаны адреса всех хостов PostgreSQL-кластера.
target_session_attrsимеет смысл указывать, если у вас более одного хоста. В статье используется алиас, которыйвсегдауказывает на PRIMARY:https://yandex.cloud/ru/docs/managed-postgresql/operations/connect#fqdn-master
Тут не задан самый главный вопрос: "Зачем нужна эта картина? Какая задача решается?"
Большие файлы стало можно использовать после появления Git LFS.
А проблему взаимодействия Git с не-программистами мы решали реализацией Subversion API поверх Git-репозитория: https://habr.com/ru/companies/vk/articles/241095/
Для совсем мелких проектов подходит почти всё, что угодно.
Проблемы начинаются когда увеличивается количество хотелок:
Хочется, чтобы в выводе сборки можно было узнать, какие тесты попадали и как?
Хочется иметь хоть какую-то статистику по тестам (тут с ностальгией вспоминаю TeamCity);
Хочется иметь разбивку по этам сборки, чтобы не нужно было искать ошибку в одном гигантском логе;
Хочется иметь нотификации авторам о падении тестов;
Хочется иметь интеграцию с системой контроля версий;
Хочется иметь возможность как-то управлять секретами;
Хочется иметь возможность делать цепочки сборок;
И т.д. и т.п.
При этом основные проблемы визуализации возникают в негативном сценарии: пока всё работает, оно никому не интересно. А вот возможность по выводу понять, что и где пошло не так, очень полезна.
Проблему безопасности можно частично решить через вынос общих запчастей в отдельную "доверенную" Jenkins Shared Library. Тогда на её код в
srcне будут распространяться ограничения песочницы, хотя наvars- всё ещё будут.На счет плагинов я с Вами согланен: в Jenkins безумное количество legacy и очень разное качество кода от плагина к плагину.
Ну и отдельная проблема в том, что там модульность доведена до абсурда: обычно функционал затрагивает сразу несколько плагинов и не всегда очевидно, какой именно за какую часть фичи отвечает.
Если сборка совсем типовая, то всю эту сложность можно попытаться спрятать, но что-то мне подсказывает, что под капотом
standardDeclarativePipelineTemplateтворится жесть.Ну и декларативный pipeline в Jenkins то еще поделие: это де-факто инструкция императивного pipeline, то есть всё равно нельзя сказать, что сделает pipeline не выполнив его.
Из-за этого, в частности:
вечно поломанная визуализация сборки;
объявления параметров и опций в pipeline влияет на следующую, а не на текущую сборку.
Когда речь заходит про CI, я всё время вспоминаю цитату из Симпсонов:
> Check out The Willie World News! I reviewed the new tractors! They're all shite!
Выбор CI выглядит как поиск наименее плохого варианта :(
Я не знаю СУБД, которые полностью поддерживающая весь ansi.
Но UPDATE входит в Core SQL Features под номером E101-03. Всё-таки весь стандарт и его Core SQL часть несколько разные вещи :)
С моей точки зрения, SQL СУБД должна соответствовать хоть одному SQL-стандарту.
Должен быть не только похожий синтаксис, но и поведение.
К примеру, запрос:
должен внутри выражений брать значения исходного кортежа, то есть поменять значения полей
aиbместами. В MySQL же в обе колонки попадёт исходное значениеb.Про особенное виденье уровней изоляции транзакций уже было выше.
Все эти особенности в MySQL документированы и переведены в категорию фичей, но от этого как-то не легче.
MySQL - это минное поле. У неё куча очень странных особенностей, которые могут вставить нож в спину в самый неожиданный момент.
Из особо прекрасного: https://www.percona.com/blog/what-if-mysqls-repeatable-reads-cause-you-to-lose-money/
Ну и, строго говоря, MySQL не является SQL СУБД.
Вы не представляете масштаб проблемы: распил проекта на маленькие модули требует годы.
Даже если предположить, что проект волшебным образом распадётся на сотни маленьких слабо связанных модулей, то их всё равно нужно будет чем-то собирать.
К тому же сокращение времени на итерацию в CI делает рефакторинг заметно комфортнее.
Распилить проект и уменьшить связанность кода это благая цель.
Но в данном случае:
уменьшение связанности никак не конфликтует с оптимизацией инструментария сборки;
уменьшение связанности кода никак нельзя назвать "простым" процессом.
"Монолит" это что?
Я так и не смог понять, как подружить IDE и Bazel...
Собственно из-за этого и пошли по пути, когда BUILD-файлы генерируются на базе исходного кода и go.mod-файлов, максимально повторяя
go build-сборку.На машинках разработчиков Bazel используется только для создания генерируемых .go-файлов, которые потом раскладываются в рабочей копии. В результате для большинства, кроме этого вызова генератора, Bazel никак не используется.
Эта схема оказалась на удивление удачной:
разработчикам не нужно воевать с Bazel;
IDE работает как работало;
генераторы получают возможность генерировать зависящие от компиляции данные (в нашем случае mock-и);
если нужно, разработчик может использовать Bazel как для сборки, так и для запроса зависимостей через
bazel query.А вот тезис с поддельным GOROOT я не понял...
40 минут это был средний результат инкрементальной сборки на 7-ми машинках в параллель. По нашим прикидкам, на одной машинке с холодным кэшем должно было быть часов 15.
В основном это время уходило на линковку тестовых бинарей: каждый пакет с тестами собирается в отдельный исполняемый файл и на это уходит чудовищное количество времени и дискового пространства.
На втором месте собственно исполнение тестов.