Тарифы сейчас с лимитом по нормальной стоимости, все что выше какого-то количества кв в месяц становится резко дорогим. Так что уже вопрос нужно ли это - искать кого-то
Общение с чатом в окне и посредством к примеру жестких промптов с использованием MPC и заранее подготовленного контекста в нужном виде - очень разные вещи, можно сказать «небо и земля»
Автор сам придумал философию Go и сам же доказывает ее не состоятельность
У меня есть замечательный пример:
Сделали приложение-монолит на Go
Потом решили заняться оптимизацией одного из модулей, переписали на C++
Потратили: 280 часов двух сильных мидлов чтобы получить 4% скорости и -30% расход RAM на одном из 8 модулей
….только вот на весь монолит от нуля до запуска потратити 600 часов
Список задач довольно ограничен, где целесообразно будет вкидывать деньги в 4% скорости и экономию RAM.
И думаю (имхо) в этом философия Go, несмотря на все недостатки и нюансы, которых к слову очень много, – Go позволяет на коленке создавать действительно очень быстрые приложения любого размера.
ПС: Очень грубо прикину, что если бы из примера писали монолит изначально на Rust потратили бы раз в 5 больше времени, но скорость была бы не 5x, а дай бог вытащили в пределах 10%
приложение на запчасти и достать от туда бизнес-логику которая имеет наивысшую ценность очень просто
Все что имеет наивысшую ценность обычно размещается на удаленном сервере с доступом а-ля API. А если вы боитесь что условно schema уведут из приложения (структуру вашего API), то от этого не спасет Rust потому что для реверса нужен MITM и 3-5 минут времени, а не HEX редактор. Периодически приходится реверс делать, даже виртуалка для этого есть специальная. Так что ничего я не упускаю, просто нет смысла об этом думать.
Целесообразнее не софт переписывать на незнакомый язык, а вкладывать силы в безопасность самого API. Это более «универсальная» защита
я не нашел вариант как заставить его жрать память
….
с которым я уже давно на короткой ноге.
Я уже понял что вы человек из серии: «говорю и сам в это верю». Команда Cloudflare публично столько шишек набило на Rust, в том числе с утечкой памяти и гонками, что ваше: «не нашел» выглядит прозаично.
По поводу Go, вот я тоже считаю что с ним на короткой ноге. Тащите рулетку, будем мерять у кого нога короче. А то у меня проблем с фантомными рейсами не бывает.
к сожалению ваш ответ подтверждает мои догадки, что знания у вас довольно поверхностные. RD от этого становится еще слабее.
PS: спасибо, хоть узнал что електрон можно разобрать. Хотя все равно при задаче вытащить schema пойду по пути МИТМ, сразу логику собираешь и не надо в коде копаться. Кстати чатгпт подсказывает что електрон можно защитить от этого
Аргументация слабая. Из разряда: «Rust даже в терминал print делает быстрее»
Я не увидел аргумента кроме размера приложения почему выбран раст. Говорю это как владелец приложения на React + Electron которое принимает 7-10к rps по UDP и все это успешно успевает отрисовывать с бека на Go, блекджеком и без всяких модулей на C++
Вообще очень сложно читать статью где автор рассказывает так между делом, что его пугает race conditions «фантомные» в Go, или там null в типизированном языке при обработке json. Оно просто сводит на нет весь вывод в конце статьи потому что очевидно, что автор «не разобрался» с теми проблемами которые были и полез в новое озеро. Даже разбор технологий из разряда: ну мы попробовали, потыкали, там что-то плохо…вы себя хотите убедить в вашем выборе что он единственный верный?
rust и C++ - хорошие языки, но только порог входа там намного выше чем в Go, особенно в задачах где есть многопоточность. Про race conditions и утечку памяти я молчу, это отдельный навык уметь делать и видеть правильную структуру приложения чтобы потом все плюсы языка не оказались его недостатками.
Увидел MongoDB перестал читать. Я их столько навосстанавливал и менял на чужих проектах, что более не хочу трогать любой софт где MongoDB присутствует. Считаю что база для «зумеров», которую создали странные люди.
Вы введите финопс в поиске хабра и отсортируйте по дате. Тут несколько разных человек рассказывают +- одну историю про 100000 и мистера забывалкина и великий финопс
И судя по отсутствию комментариев и просмотров на этих статьях - они со своим «финопсом» задрали большую часть хабра. Сплошная вода в каждой статье с чтением мантры «финопс круто, финопс классно». В моей реальности у кого не спрошу, никто вообще его не слышал. Когда говоришь: «ну это типа когда оптимизируешь затраты на облако» на тебя смотрят как на дебила.
Я надеялся что в ответе вы расскажите куда ваше решение можно использовать и самое главное как в тяжелом проде. Но видимо я попал в статью теоретика, а не практика.
И вас с облегчением, раз вы написали статью в раздел мнения, а другие мнения вам не интересны
Я понимаю задачу и понимаю автора, но не понимаю что за задачу надо решать в реальной жизни.
Поясняю. Данный пример можно решить таким способом, но это задача в вакууме. Если мы в реальный мир выходим, то все таки описанная задача будет решаться базой с транзакционной моделью для сохранения консистентности данных.
Самое печальное вообще в самом примере, что независимо от пакета при вызове log.{что-то там}() приходим к fmt пакету. Т.е функции которая выполняется и тратит такты на свою работу и тормозит общий поток. Тут предлагается сделать еще агрегирование лога (т.е еще больше ресурсов потратить) чтобы что? Чтобы удобно было по grep поискать?
Да вы можете сказать, заверни ее в буф канал и будете правы. Только вот в чем вопрос, а если у вас буф канал на log, то зачем вам вообще лог подобного формата в файле. Т.е буф канал сразу ставит крест на том что это критически важные логи, т.к если будет паника - поток падает и часть лога в буф канале исчезнет
Отсюда можно сделать очень простой вывод: либо лог нужен для того чтобы отслеживать состояние программы, с минимальными нагрузками до состояния чек-поинтов чтобы в критической ситуации понять где сбой (точнее после чего) без создания очереди, либо использовать что-то другое в том числе базы данных где тупо оптимизация и стабильность выше и можно хоть миллионами запросов пулять.
спасибо автору что поделился своим видением, но противник идей где логи являются bottleneck производительности. И не знаю как другие делают, а у нас даже сборки отдельные //go:build !debug чтобы инструкции log.Debug просто вырезались при компиляции и лишнюю нагрузку не вызывали.
PS: я тут код посмотрел, пф, понимаю что он для примера..но ептить, там аллокация на аллокации, и аллокацией погоняет. Имхо мне бы стыдно было такой код показывать, но пускай остается на совести автора.
Хочу поделиться, Решали задачу подобного плана, и одно время стоял joniter. Это самый быстрый пакет который нашли, но в итоге ушли в пользу самописного ручного «прохода»
В задаче было 4 типа сообщений с заранее известной формой, и они могли еще объединятся в «массивы». Скорость сообщений на входе в пиках 200-250к rps (примерно около 800мбит утилизировали в пиках)
Схема примерно такая получилась
Посмотреть первый байт, если там [, значит прилетел массив и он улетает на функцию которая посимвольно пролетает по всей строке и делит }, и возвращает обратно в поток для дальнейшего разбора
Если нет, значит измеряем количество байт и кидаем в один из 4 потоков на обработку (каждый тип сообщения имел разный размер)
Далее захватывали конкретные байты по местоположению и читаем выдергивая контент по типу.
Делали из размышлений: «а почему бы и нет» из разряда мозги прогреть, поэтому ожиданий никаких не было. В итоге joniter обогнали в 4 раза, а отрыв при большом потоке оказался еще больше
Мораль этой истории такова: joniter крутой пакет, но можно быстрее если сообщения стандартизированы
PS: метод преподготовки (деления массива на отдельные чанки и разделения типов сообщений) было изначально реализовано для joniter. Т.е мы точно выжали все что могли..
Даже не скрываю этого и эти мысли иногда посещают, что вот когда-нибудь оно откажет. Один жирный плюс на противовесе – структуры приложений, – вся конфигурация подтягивается один раз и работает сутки. Очень редкий кейс PUSH новых настроек. Т.е отвалится mysql или конфигуратор, приложения продолжат работу. Но то что надо этим вопросом заняться и вообщем-то в эпоху chatgpt – дело реально 15 минут все прекрасно понимают. Не можем выбрать верную схему. Из вариантов которые рассматриваем – API точка на каждом приложении, которая сразу вещает схему и позволяет менять параметры приложения. Рисует GUI который подтягивает список всех приложений которые сейчас работают, там есть некий endpoint где GUI может получить схему которую можно менять и выводит формы необходимые. Ты меняешь что-то и через отдельный endpoint настройки сразу пушится в приложение. Но этот вариант уже не 15 минут + надо будет отладку делать перед добавлением в продакшен
У нас сейчас все хранится в mysql базе, GUI и сервер раздачи написал chatgpt. Нам надо было срочно решение с GUI. Пакет тоже написал chatgpt для стыковки. Сейчас стараемся во весь софт сделать это обновление.
При старте приложения просто ./app --config=имя_приложения
Он по имени обращается на API вшитый в код и ему отдается JSON готовый из базы. Сделано на коленке, увы пока так и времени доделать нет. Но работает уже год и все довольны. Осталось весь софт перевести на эту историю
Вообще считаю что mysql это была ошибка, потенциальная точка отказа. Лучше в файлах...
Вот кстати ваш формат можно было к этому приспособить...т.к вы сами предположили что конфиги могут быть большими...Ну пускай в одном файле будет сразу много конфигураций и при запросе нужный кусок отдается по HTTP
Основная беда в том что mysql очень плохо переживает сбои если не настроена репликация (пс у нас она не настроена), т.е если что у нас будут веселые ночи. Если бы конфигурация была упакована в единый файл к примеру с вашим форматом...то вопрос бекапа – вопрос простого копирования. И если что-то случилось можно быстро перекинуть бек и загрузить новый экземпляр раздачи.
Этот вопрос почти в вакууме, но у меня есть пример монолитного приложения и которое на prod жрет как не в себя. После деплоя в папке лежит test.yaml / prod.yaml. Для проверки на prod после deploy мы запускаем с test.yaml где зажаты все гайки в том числе количество потоков и ограничения (просто для проверки что приложение запускается и корректно переваривает данные), далее уже запускаем as service, но с prod.yaml.
Поэтому задачу stg/prod я решал бы абсолютно так же, просто в конфиге прописывались все ограничения или даже вводим бы вшитый механизм а-ля ключ запуска: stg/prod, в том числе можно вшить механизм оценки того сколько конкретная "машина" может держать потоков на базе информации о системе.
Другое вопрос если у вас в конфиге например ограничения описываются более чем 2-3 переменными (как в моем примере, т.к у нас все ограничения потоков описаны двумя строчками конфигурации).
Я понимаю что можно сделать монолит поставив к примеру 100500 endpoint точек API и на каждую повесить воркер с ограничением и потом успешно это в конфигурацию вынести отдельно, но опять же такие истории предполагают уж изменения конфигурации налету. При deploy нового подобного приложения собирается аналитика или при атаке на endpoint вносятся PUSH ограничения и тут мы опять приходим к централизации и GUI
Я рад что есть разработчики которые делают простыни конфигураций, к примеру такие можно найти на mysql и прочий софт. Но там хорошо, настроил один раз и забыл на большой период времени (в большинстве случаев)
Но если конфиги такие что еще надо постоянно что-то там менят, подкручивать или объединять и это сотнями строк в yaml/conf/ATMC файлах и все это без GUI – то думаю для таких программистов в аду есть отдельный котел
К слову, мы для своих систем писали раздачу конфигурации с сервера, т.е в приложение вшито или в конфиге адрес API точки доступа куда приложение обращается при запуске и тянет с сервера ту конфигурацию которая актуальна и можно даже пушить настройки + GUI где можно поменять настройки полностью для любого приложения. Когда мы создавали пакеты, ничего подобного и дельного не нашли. Вот таких систем не хватает...PS: Хотя может плохо искали
Почему вы считаете, что ATMC нельзя так же править руками?
Просто для меня скобки фигурные которые показывают вложенность – не humanlike формат, вот и все
На мой взгляд его править даже удобнее, чем тот же yml, потому что в nano не видно ни пробелов ни табов и ошибиться с отступом в большом конфиге будет очень просто
При аварийной правке есть гениально простые решения:
В корне лежит всегда default.yaml/conf как пример
При редактировании конфигурация копируется с приставкой backup
Это позволяет полностью забыть о спецсиволах даже когда накосячил с ними, все восстанавливается или просто копируется из существующих Ну а если прям задача найти проблема: "cat -A файл" отобразит скрытое
Странно что я это объясняю, будто бы вы не понимаете как реально строится программное обеспечение
Даже в IDE часто можно затупить с отступом. В прочем со скобкой тоже можно затупить:)
Возможно "Даже" возникнет в вашем IDE, и тут только совет его поменять. А к примеру в VSCode затупить с yaml конфигурацией - это что-то нереальное. На тему скобок, тут тоже вопросы. На тему скобок тоже не понимаю, не помню вообще когда последний раз скобки ставил клавишей. Конкретный IDE на Golang по первым буквам func/switch+Enter сразу рисует необходимый блок автоматически со всеми скобками и ставит указатель на имя, потом +tab и можно заполнить аргументы...и тд
Безос своему ИИ-агенту: Надо оптимизировать как-то доходы!
ИИ-Агент: Сделано!
Тарифы сейчас с лимитом по нормальной стоимости, все что выше какого-то количества кв в месяц становится резко дорогим. Так что уже вопрос нужно ли это - искать кого-то
Когда курица несет золотые яйца, зачем говорить что она у тебя есть?
Общение с чатом в окне и посредством к примеру жестких промптов с использованием MPC и заранее подготовленного контекста в нужном виде - очень разные вещи, можно сказать «небо и земля»
Автор сам придумал философию Go и сам же доказывает ее не состоятельность
У меня есть замечательный пример:
Сделали приложение-монолит на Go
Потом решили заняться оптимизацией одного из модулей, переписали на C++
Потратили: 280 часов двух сильных мидлов чтобы получить 4% скорости и -30% расход RAM на одном из 8 модулей
….только вот на весь монолит от нуля до запуска потратити 600 часов
Список задач довольно ограничен, где целесообразно будет вкидывать деньги в 4% скорости и экономию RAM.
И думаю (имхо) в этом философия Go, несмотря на все недостатки и нюансы, которых к слову очень много, – Go позволяет на коленке создавать действительно очень быстрые приложения любого размера.
ПС: Очень грубо прикину, что если бы из примера писали монолит изначально на Rust потратили бы раз в 5 больше времени, но скорость была бы не 5x, а дай бог вытащили в пределах 10%
С чего вдруг IDE - плохие гарантии, когда практически любой IDE работает в паре с интерпретатором Go
Wails вас чем не устроил?
Все что имеет наивысшую ценность обычно размещается на удаленном сервере с доступом а-ля API. А если вы боитесь что условно schema уведут из приложения (структуру вашего API), то от этого не спасет Rust потому что для реверса нужен MITM и 3-5 минут времени, а не HEX редактор. Периодически приходится реверс делать, даже виртуалка для этого есть специальная. Так что ничего я не упускаю, просто нет смысла об этом думать.
Целесообразнее не софт переписывать на незнакомый язык, а вкладывать силы в безопасность самого API. Это более «универсальная» защита
Я уже понял что вы человек из серии: «говорю и сам в это верю». Команда Cloudflare публично столько шишек набило на Rust, в том числе с утечкой памяти и гонками, что ваше: «не нашел» выглядит прозаично.
По поводу Go, вот я тоже считаю что с ним на короткой ноге. Тащите рулетку, будем мерять у кого нога короче. А то у меня проблем с фантомными рейсами не бывает.
к сожалению ваш ответ подтверждает мои догадки, что знания у вас довольно поверхностные. RD от этого становится еще слабее.
PS: спасибо, хоть узнал что електрон можно разобрать. Хотя все равно при задаче вытащить schema пойду по пути МИТМ, сразу логику собираешь и не надо в коде копаться. Кстати чатгпт подсказывает что електрон можно защитить от этого
Аргументация слабая. Из разряда: «Rust даже в терминал print делает быстрее»
Я не увидел аргумента кроме размера приложения почему выбран раст. Говорю это как владелец приложения на React + Electron которое принимает 7-10к rps по UDP и все это успешно успевает отрисовывать с бека на Go, блекджеком и без всяких модулей на C++
Вообще очень сложно читать статью где автор рассказывает так между делом, что его пугает race conditions «фантомные» в Go, или там null в типизированном языке при обработке json. Оно просто сводит на нет весь вывод в конце статьи потому что очевидно, что автор «не разобрался» с теми проблемами которые были и полез в новое озеро. Даже разбор технологий из разряда: ну мы попробовали, потыкали, там что-то плохо…вы себя хотите убедить в вашем выборе что он единственный верный?
rust и C++ - хорошие языки, но только порог входа там намного выше чем в Go, особенно в задачах где есть многопоточность. Про race conditions и утечку памяти я молчу, это отдельный навык уметь делать и видеть правильную структуру приложения чтобы потом все плюсы языка не оказались его недостатками.
Там деньги через крипту финально отправили, а это уже минимум поток Финансы и IT ;)
Увидел MongoDB перестал читать. Я их столько навосстанавливал и менял на чужих проектах, что более не хочу трогать любой софт где MongoDB присутствует. Считаю что база для «зумеров», которую создали странные люди.
Вы введите финопс в поиске хабра и отсортируйте по дате. Тут несколько разных человек рассказывают +- одну историю про 100000 и мистера забывалкина и великий финопс
И судя по отсутствию комментариев и просмотров на этих статьях - они со своим «финопсом» задрали большую часть хабра. Сплошная вода в каждой статье с чтением мантры «финопс круто, финопс классно». В моей реальности у кого не спрошу, никто вообще его не слышал. Когда говоришь: «ну это типа когда оптимизируешь затраты на облако» на тебя смотрят как на дебила.
Я надеялся что в ответе вы расскажите куда ваше решение можно использовать и самое главное как в тяжелом проде. Но видимо я попал в статью теоретика, а не практика.
И вас с облегчением, раз вы написали статью в раздел мнения, а другие мнения вам не интересны
Я понимаю задачу и понимаю автора, но не понимаю что за задачу надо решать в реальной жизни.
Поясняю. Данный пример можно решить таким способом, но это задача в вакууме. Если мы в реальный мир выходим, то все таки описанная задача будет решаться базой с транзакционной моделью для сохранения консистентности данных.
Самое печальное вообще в самом примере, что независимо от пакета при вызове log.{что-то там}() приходим к fmt пакету. Т.е функции которая выполняется и тратит такты на свою работу и тормозит общий поток. Тут предлагается сделать еще агрегирование лога (т.е еще больше ресурсов потратить) чтобы что? Чтобы удобно было по grep поискать?
Да вы можете сказать, заверни ее в буф канал и будете правы. Только вот в чем вопрос, а если у вас буф канал на log, то зачем вам вообще лог подобного формата в файле. Т.е буф канал сразу ставит крест на том что это критически важные логи, т.к если будет паника - поток падает и часть лога в буф канале исчезнет
Отсюда можно сделать очень простой вывод: либо лог нужен для того чтобы отслеживать состояние программы, с минимальными нагрузками до состояния чек-поинтов чтобы в критической ситуации понять где сбой (точнее после чего) без создания очереди, либо использовать что-то другое в том числе базы данных где тупо оптимизация и стабильность выше и можно хоть миллионами запросов пулять.
спасибо автору что поделился своим видением, но противник идей где логи являются bottleneck производительности. И не знаю как другие делают, а у нас даже сборки отдельные //go:build !debug чтобы инструкции log.Debug просто вырезались при компиляции и лишнюю нагрузку не вызывали.
PS: я тут код посмотрел, пф, понимаю что он для примера..но ептить, там аллокация на аллокации, и аллокацией погоняет. Имхо мне бы стыдно было такой код показывать, но пускай остается на совести автора.
Хочу поделиться, Решали задачу подобного плана, и одно время стоял joniter. Это самый быстрый пакет который нашли, но в итоге ушли в пользу самописного ручного «прохода»
В задаче было 4 типа сообщений с заранее известной формой, и они могли еще объединятся в «массивы». Скорость сообщений на входе в пиках 200-250к rps (примерно около 800мбит утилизировали в пиках)
Схема примерно такая получилась
Посмотреть первый байт, если там [, значит прилетел массив и он улетает на функцию которая посимвольно пролетает по всей строке и делит }, и возвращает обратно в поток для дальнейшего разбора
Если нет, значит измеряем количество байт и кидаем в один из 4 потоков на обработку (каждый тип сообщения имел разный размер)
Далее захватывали конкретные байты по местоположению и читаем выдергивая контент по типу.
Делали из размышлений: «а почему бы и нет» из разряда мозги прогреть, поэтому ожиданий никаких не было. В итоге joniter обогнали в 4 раза, а отрыв при большом потоке оказался еще больше
Мораль этой истории такова: joniter крутой пакет, но можно быстрее если сообщения стандартизированы
PS: метод преподготовки (деления массива на отдельные чанки и разделения типов сообщений) было изначально реализовано для joniter. Т.е мы точно выжали все что могли..
Даже не скрываю этого и эти мысли иногда посещают, что вот когда-нибудь оно откажет. Один жирный плюс на противовесе – структуры приложений, – вся конфигурация подтягивается один раз и работает сутки. Очень редкий кейс PUSH новых настроек. Т.е отвалится mysql или конфигуратор, приложения продолжат работу.
Но то что надо этим вопросом заняться и вообщем-то в эпоху chatgpt – дело реально 15 минут все прекрасно понимают. Не можем выбрать верную схему. Из вариантов которые рассматриваем – API точка на каждом приложении, которая сразу вещает схему и позволяет менять параметры приложения. Рисует GUI который подтягивает список всех приложений которые сейчас работают, там есть некий endpoint где GUI может получить схему которую можно менять и выводит формы необходимые. Ты меняешь что-то и через отдельный endpoint настройки сразу пушится в приложение. Но этот вариант уже не 15 минут + надо будет отладку делать перед добавлением в продакшен
У нас сейчас все хранится в mysql базе, GUI и сервер раздачи написал chatgpt. Нам надо было срочно решение с GUI.
Пакет тоже написал chatgpt для стыковки. Сейчас стараемся во весь софт сделать это обновление.
При старте приложения просто ./app --config=имя_приложения
Он по имени обращается на API вшитый в код и ему отдается JSON готовый из базы. Сделано на коленке, увы пока так и времени доделать нет. Но работает уже год и все довольны. Осталось весь софт перевести на эту историю
Вообще считаю что mysql это была ошибка, потенциальная точка отказа. Лучше в файлах...
Вот кстати ваш формат можно было к этому приспособить...т.к вы сами предположили что конфиги могут быть большими...Ну пускай в одном файле будет сразу много конфигураций и при запросе нужный кусок отдается по HTTP
Основная беда в том что mysql очень плохо переживает сбои если не настроена репликация (пс у нас она не настроена), т.е если что у нас будут веселые ночи. Если бы конфигурация была упакована в единый файл к примеру с вашим форматом...то вопрос бекапа – вопрос простого копирования. И если что-то случилось можно быстро перекинуть бек и загрузить новый экземпляр раздачи.
Этот вопрос почти в вакууме, но у меня есть пример монолитного приложения и которое на prod жрет как не в себя. После деплоя в папке лежит test.yaml / prod.yaml.
Для проверки на prod после deploy мы запускаем с test.yaml где зажаты все гайки в том числе количество потоков и ограничения (просто для проверки что приложение запускается и корректно переваривает данные), далее уже запускаем as service, но с prod.yaml.
Поэтому задачу stg/prod я решал бы абсолютно так же, просто в конфиге прописывались все ограничения или даже вводим бы вшитый механизм а-ля ключ запуска: stg/prod, в том числе можно вшить механизм оценки того сколько конкретная "машина" может держать потоков на базе информации о системе.
Другое вопрос если у вас в конфиге например ограничения описываются более чем 2-3 переменными (как в моем примере, т.к у нас все ограничения потоков описаны двумя строчками конфигурации).
Я понимаю что можно сделать монолит поставив к примеру 100500 endpoint точек API и на каждую повесить воркер с ограничением и потом успешно это в конфигурацию вынести отдельно, но опять же такие истории предполагают уж изменения конфигурации налету. При deploy нового подобного приложения собирается аналитика или при атаке на endpoint вносятся PUSH ограничения и тут мы опять приходим к централизации и GUI
Я рад что есть разработчики которые делают простыни конфигураций, к примеру такие можно найти на mysql и прочий софт. Но там хорошо, настроил один раз и забыл на большой период времени (в большинстве случаев)
Но если конфиги такие что еще надо постоянно что-то там менят, подкручивать или объединять и это сотнями строк в yaml/conf/ATMC файлах и все это без GUI – то думаю для таких программистов в аду есть отдельный котел
К слову, мы для своих систем писали раздачу конфигурации с сервера, т.е в приложение вшито или в конфиге адрес API точки доступа куда приложение обращается при запуске и тянет с сервера ту конфигурацию которая актуальна и можно даже пушить настройки + GUI где можно поменять настройки полностью для любого приложения. Когда мы создавали пакеты, ничего подобного и дельного не нашли. Вот таких систем не хватает...PS: Хотя может плохо искали
Просто для меня скобки фигурные которые показывают вложенность – не humanlike формат, вот и все
При аварийной правке есть гениально простые решения:
В корне лежит всегда default.yaml/conf как пример
При редактировании конфигурация копируется с приставкой backup
Это позволяет полностью забыть о спецсиволах даже когда накосячил с ними, все восстанавливается или просто копируется из существующих
Ну а если прям задача найти проблема: "cat -A файл" отобразит скрытое
Странно что я это объясняю, будто бы вы не понимаете как реально строится программное обеспечение
Возможно "Даже" возникнет в вашем IDE, и тут только совет его поменять. А к примеру в VSCode затупить с yaml конфигурацией - это что-то нереальное. На тему скобок, тут тоже вопросы. На тему скобок тоже не понимаю, не помню вообще когда последний раз скобки ставил клавишей. Конкретный IDE на Golang по первым буквам func/switch+Enter сразу рисует необходимый блок автоматически со всеми скобками и ставит указатель на имя, потом +tab и можно заполнить аргументы...и тд