Re[6]: лучшие практики для настроек-конфигов приложения..
От: Kolesiki  
Дата: 23.03.21 13:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>почему это "дурь" — решительно непонятно.


Потому что конфиг — это вообще не про код. Код должен быть в программе, а в конфиге — лишь "настроечные величины". Если ты налепил конфиг в виде кода, ты явно решил задачу левым путём. Времена ЛИСПа прошли и не потому, что ЛИСП устарел — он просто непригоден для надёжного ПО — как раз в силу идеи "данные как код".
Re[3]: лучшие практики для настроек-конфигов приложения..
От: scf  
Дата: 23.03.21 13:45
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Это такая 1-апрельская шутка штоле??

K>Эта бредятина документирована на 14(!!!!) страницах. С виду — какой-то гибрид макросов и JSON. На деле — переусложнённая хрень, где в JSON просто вмешали какие-то местечковые задачки. Поверь старому анжанеру — это г****вно не взлетит. Даже hi_octane с его "кодом-как-конфиг" (дырявым донельзя) имеет бóльшие шансы.

5k звезд на гитхабе, массово применяется в серверном софте, де факто стандарт для Scala разработчиков, просачивается и в Java.
Re[7]: лучшие практики для настроек-конфигов приложения..
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.03.21 09:15
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Потому что конфиг — это вообще не про код. Код должен быть в программе, а в конфиге — лишь "настроечные величины". Если ты налепил конфиг в виде кода, ты явно решил задачу левым путём. Времена ЛИСПа прошли и не потому, что ЛИСП устарел — он просто непригоден для надёжного ПО — как раз в силу идеи "данные как код".

Очень странный набор необоснованных утверждений.
Что такое "настроечные величины"? Начинается всё обычно невинно: ну там, "номер порта, на котором слушать", "фолдер, куда складывать логи".
Потом постепенно вырастают идеи типа "а давайте у нас приложение будет поставляться в виде набора универсальных кубиков, которые мы будем склеивать в рантайме в соответствии с конфигурацией".
Начиная от "запросы по адресам '/users/*' будет обрабатывать UserRequestHandler, а по адресам '/dicpics/*.png' — StaticContentHandler", и заканчивая "на форме UserProfileForm в координатах 100, 200 разместить кнопку размером 128*32 с текстом 'Ok', по нажатию выполнить метод UserProfileForm.OnOkClick".
И вот — не успеешь оглянуться, а у тебя целый язык описания конфигураций; исходники на нём занимают мегабайты. Вот только тулчейна для него либо нет никакого, либо есть заведомо убогий.
Вот, покажите мне рефакторинг тул для веб конфига, который бы умел "перенести правило на уровень выше" или, наоборот "перенести правило на уровень ниже". Или "разделить правило на два". Нету, увы.
Почему? Потому, что это отдельный xml-based недоязык для конфигурации.

Лисп в качестве языка программирования плох потому, что идёт от обратного, от "код как данные". В качестве языка конфигурирования он как раз ничуть не хуже самого себя.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: лучшие практики для настроек-конфигов приложения..
От: Sharov Россия  
Дата: 24.03.21 09:35
Оценка:
Здравствуйте, MadHuman, Вы писали:


MH>2. противоположный 1-му подходу. на старте создаем некий IConfigProvider и далее через него все подсистемы сами читают что им нужно.
MH>+ каждая подсистема сама читает нужные настройки, при возникновении в ней новых — не надо править центральное место.

MH>- нет единого места, где все перечислены (хотя можно доку написать и поддерживать).
MH>что показывает практика, что лучше в долгую в среднем/большом проекте? единый класс-конфиг или каждый читает сам что нужно?
MH>3. стандартный в .net подход с appsettings.
MH>у меня не пошел. много церемоний, сложнее понимать.


А в чем проблема совмещать 2 и 3 -- каждую секцию вычитывать своим IConfigProvider из одного файла appsettings?
Кодом людям нужно помогать!
Re[2]: лучшие практики для настроек-конфигов приложения..
От: MadHuman Россия  
Дата: 24.03.21 09:48
Оценка:
Здравствуйте, hi_octane, Вы писали:

MH>>в каком формате хранить?

_>Последние несколько моих (наиболее успешных) проектов хранят конфиг в виде C# кода. При старте конфиг компилируется и запускает всё приложение.
а чем отличается от варианта 1 ?

1. где-то заранее (в Startup/Init) читаем в спец класс-конфиг (в нём каждая проперть соотвествует какой-то конфиг-настройке).


по сути тоже — есть в итоге код (класс с пропертями), но более безопасно.
обычно в конфиге значения, логики нет... или у вас есть? зачем?
Re[8]: лучшие практики для настроек-конфигов приложения..
От: Ночной Смотрящий Россия  
Дата: 24.03.21 13:13
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Начиная от "запросы по адресам '/users/*' будет обрабатывать UserRequestHandler, а по адресам '/dicpics/*.png' — StaticContentHandler",


Совершенно стандартная фича взрослого веб-сервера. И все они как то обходятся без компиляции кода.

S>и заканчивая "на форме UserProfileForm в координатах 100, 200 разместить кнопку размером 128*32 с текстом 'Ok', по нажатию выполнить метод UserProfileForm.OnOkClick".


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

S>И вот — не успеешь оглянуться, а у тебя целый язык описания конфигураций; исходники на нём занимают мегабайты.


Тут уместна пословица про стеклянный пенис.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: лучшие практики для настроек-конфигов приложения..
От: Ночной Смотрящий Россия  
Дата: 24.03.21 13:15
Оценка: :)
Здравствуйте, Sharov, Вы писали:

S>MH>2. противоположный 1-му подходу. на старте создаем некий IConfigProvider и далее через него все подсистемы сами читают что им нужно.

MH>>+ каждая подсистема сама читает нужные настройки, при возникновении в ней новых — не надо править центральное место.

MH>>- нет единого места, где все перечислены (хотя можно доку написать и поддерживать).
MH>>что показывает практика, что лучше в долгую в среднем/большом проекте? единый класс-конфиг или каждый читает сам что нужно?
S>MH>3. стандартный в .net подход с appsettings.
MH>>у меня не пошел. много церемоний, сложнее понимать.
S>


S>А в чем проблема совмещать 2 и 3 -- каждую секцию вычитывать своим IConfigProvider из одного файла appsettings?


Он жен написал, "у меня не пошел". Что тут можно обсуждать?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: лучшие практики для настроек-конфигов приложения..
От: Sharov Россия  
Дата: 24.03.21 13:17
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>А в чем проблема совмещать 2 и 3 -- каждую секцию вычитывать своим IConfigProvider из одного файла appsettings?


НС>Он жен написал, "у меня не пошел". Что тут можно обсуждать?


Не пошел отдельно 3, а вот в связке 2+3 может и пошло бы.
Кодом людям нужно помогать!
Re[4]: лучшие практики для настроек-конфигов приложения..
От: Ночной Смотрящий Россия  
Дата: 24.03.21 13:29
Оценка:
Здравствуйте, Sharov, Вы писали:

НС>>Он жен написал, "у меня не пошел". Что тут можно обсуждать?

S>Не пошел отдельно 3, а вот в связке 2+3 может и пошло бы.

Озвученные причины: "много церемоний, сложнее понимать". В связке с п.2 эти причины только усугубляются.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: лучшие практики для настроек-конфигов приложения..
От: IT Россия linq2db.com
Дата: 24.03.21 16:31
Оценка: 17 (4)
Здравствуйте, MadHuman, Вы писали:

MH>Коллеги, поделитесь опытом к каким практикам для организации работы с настройками в приложениях/сервисах пришли и почему..


Расскажу как это делается у нас правильно.

Конфиги типа сохранения размера окошек и других причуд пользователя — это отдельный разговор и вроде как стандартный Settings работает неплохо.

Тут будет про настройки самого приложения для различных окружений типа PROD, UAT, QA, DEV, TEST и т.п.

В качестве source имеется json следующего вида:

[
  {
    "Schema"  : "dbo",
    "Table"   : "Property",
    "Columns" : [ "Category", "Name", "Environment", "Value", "Type" ]
    "Data"    :
    [
      [ "Mail",                           "Host",              "DEFAULT",    "lalala.yoyoyo.com",            "string" ],
      [ "Mail",                           "Port",              "DEFAULT",    "25",                           "int"    ],
      [ "Mail.From",                      "LaLaLaNotifyEmail", "DEFAULT",    "lalala.dev@yoyoyo.com",        "string" ],
      [ "Mail.From",                      "LaLaLaNotifyEmail", "UAT",        "lalala.uat@yoyoyo.com",        "string" ],
      [ "Mail.From",                      "LaLaLaNotifyEmail", "PROD",       "lalala@yoyoyo.com",            "string" ],
      [ "Mail.To",                        "Support",           "DEVAULT",    "",                             "string" ],
      [ "Mail.To",                        "Support",           "DEV,QA,UAT", "lalala.developers@yoyoyo.com", "string" ],
      [ "Mail.To",                        "Support",           "PROD",       "lalala.support@yoyoyo.com",    "string" ],
      [ "PostProcessor.UpdateStatistics", "CommandTimeout",    "DEFAULT",    "0",                            "int"    ],
      [ "PostProcessor.UpdateStatistics", "CommandTimeout",    "PROD",       "720",                          "int"    ],

      ... ещё пару сотен переменных
    ]
  }
]

По этому файлу генерируется SQL скрипт:

-- [dbo].[Property]
--
MERGE INTO [dbo].[Property] AS Target
USING
(
    VALUES
    ( N'Mail',                           N'Host',              N'DEFAULT',    N'lalala.yoyoyo.com',            N'string' ),
    ( N'Mail',                           N'Port',              N'DEFAULT',    N'25',                           N'int'    ),
    ( N'Mail.From',                      N'LaLaLaNotifyEmail', N'DEFAULT',    N'lalala.dev@yoyoyo.com',        N'string' ),
    ( N'Mail.From',                      N'LaLaLaNotifyEmail', N'UAT',        N'lalala.uat@yoyoyo.com',        N'string' ),
    ( N'Mail.From',                      N'LaLaLaNotifyEmail', N'PROD',       N'lalala@yoyoyo.com',            N'string' ),
    ( N'Mail.To',                        N'Support',           N'DEVAULT',    N'',                             N'string' ),
    ( N'Mail.To',                        N'Support',           N'DEV,QA,UAT', N'lalala.developers@yoyoyo.com', N'string' ),
    ( N'Mail.To',                        N'Support',           N'PROD',       N'lalala.support@yoyoyo.com',    N'string' ),
    ( N'PostProcessor.UpdateStatistics', N'CommandTimeout',    N'DEFAULT',    N'0',                            N'int'    ),
    ( N'PostProcessor.UpdateStatistics', N'CommandTimeout',    N'PROD',       N'7200',                         N'int'    ),

      ... ещё пару сотен переменных
)
AS Source (...)
ON ...
WHEN MATCHED ...
WHEN NOT MATCHED BY Target ...
WHEN NOT MATCHED BY Source ...
;

Дополнительно генерируется C# файл:

static partial LaLaLaProperty
{
    public static partial class Mail
    {
        private static string _Host;
        public  static string Host { get { return _Host; } set { _Host = value; } }
        private static string _Port;
        public  static string Port { get { return _Port; } set { _Port = value; } }

        public static partial class From
        {
            private static string _LaLaLaNotifyEmail;
            public  static string  LaLaLaNotifyEmail { get { _LaLaLaNotifyEmail; } set { _LaLaLaNotifyEmail = value; } }
        }

        public static partial class To
        {
            private static string _CommandTimeout;
            public  static string  CommandTimeout { get { return _CommandTimeout; } set { _CommandTimeout = value; } }
        }
    }

    public static partial class PostProcessor
    {
        public static partial class To
        {
            private static string _Support;
            public  static string  Support { get { return _Support; } set { _Support = value; } }
        }
    }

    static void SetProperties()
    {
        Mail.Host                                      = GetValue<string>("Mail",                           "Host");
        Mail.Port                                      = GetValue<int>   ("Mail",                           "Port");
        Mail.From.LaLaLaNotifyEmail                    = GetValue<string>("Mail.From",                      "LaLaLaNotifyEmail");
        Mail.To.Support                                = GetValue<string>("Mail.To",                        "Support");
        PostProcessor.UpdateStatistics.CommandTimeoutt = GetValue<string>("PostProcessor.UpdateStatistics", "CommandTimeout");
    }
}

Далее SQL скрипт деплоится в каждое окружение, а в коде мы имеем возможность использовать настройки в привычном типизированном виде:

SendMail(Mail.Host, Mail.Port, ...);

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

Итого. Для добавления настройки разработчику необходимо добавить её в json файл и запустить Run Custorm Tool для сообтветствующего T4, после чего она готова к употреблению.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: лучшие практики для настроек-конфигов приложения..
От: Ночной Смотрящий Россия  
Дата: 26.03.21 11:56
Оценка:
Здравствуйте, IT, Вы писали:

IT>Итого. Для добавления настройки разработчику необходимо добавить её в json файл и запустить Run Custorm Tool для сообтветствующего T4, после чего она готова к употреблению.


Это ты какой то велосипед придумал. Зачем настройки в РСУБД хранить? Зачем генерить класс по json?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: лучшие практики для настроек-конфигов приложения..
От: IT Россия linq2db.com
Дата: 26.03.21 13:32
Оценка: 1 (1)
Здравствуйте, Ночной Смотрящий, Вы писали:

IT>>Итого. Для добавления настройки разработчику необходимо добавить её в json файл и запустить Run Custorm Tool для сообтветствующего T4, после чего она готова к употреблению.

НС>Это ты какой то велосипед придумал. Зачем настройки в РСУБД хранить? Зачем генерить класс по json?

Здрасти. Велосипеды — это наше всё! Лучше своя хорошо контролируемая самоделка, которую в любой момент можно переделать в любую сторону, чем рукожопный кусок непонятно чего с гитхаба. На то, что у меня уходит до недели работы, я предпачитаю велосипедить сам. Потом меньше проблем.

Что касается РСУБД, то это вопрос философский. Когда это только делалось я сам вопрошал коллег а нужна ли здесь СУБД? Как часто мы меняем настройки между релизами? Решили, что пусть будет. А вдруг. Хотя за всё время эксплуатации системы не припомню, чтобы это делалось. Хотя я не уверен.

Про json не понял. Ты предлагаешь не генерировать класс, а каждый раз парсить json или наоборот?
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: лучшие практики для настроек-конфигов приложения..
От: Kolesiki  
Дата: 28.03.21 10:54
Оценка: -1 :)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Kolesiki, Вы писали:


K>>Потому что конфиг — это вообще не про код. Код должен быть в программе, а в конфиге — лишь "настроечные величины". Если ты налепил конфиг в виде кода, ты явно решил задачу левым путём. Времена ЛИСПа прошли и не потому, что ЛИСП устарел — он просто непригоден для надёжного ПО — как раз в силу идеи "данные как код".


S>Очень странный набор необоснованных утверждений.


Если ты что-то недопонимаешь, это не повод называть "безосновательные". Это повод задуматься: "А не слишком ли я глух к чужим словам, считая своё решение самым правильным?".

S>Что такое "настроечные величины"? Начинается всё обычно невинно: ну там, "номер порта, на котором слушать"


Именно! "настроечные величины" и есть самые простейшие скаляры, которыми "подстраивается" программа. Т.е. код — неизменен, изменяются лишь параметры.

S>Потом постепенно вырастают идеи типа "а давайте у нас приложение будет поставляться в виде набора универсальных кубиков, которые мы будем склеивать в рантайме в соответствии с конфигурацией".


Ну так ты вообще про другое — ПРО ПЛАГИНЫ! К каждому из которых, прикинь, можно тоже поставлять конфиг простейших величин.

S>Начиная от "запросы по адресам '/users/*'...


Местечковая галиматья. НЕТ у конфигов задачи "запросы по адресам". Это твоя бизнес-задача, решённая через одно неприличное место.
Ещё раз вернись в место, где про "простейшие величины" — вот конфиг — это оно. При всех порочных практиках, самое ужасное, что ты можешь сделать — позволить чему-то внешнему исполняться на хосте.
Re[4]: лучшие практики для настроек-конфигов приложения..
От: Kolesiki  
Дата: 28.03.21 10:59
Оценка: 3 (1)
Здравствуйте, scf, Вы писали:

scf>5k звезд на гитхабе, массово применяется в серверном софте, де факто стандарт для Scala разработчиков, просачивается и в Java.


Ну это как "самый популярный тиктокер" — сам понимаешь, репутация не самая впечатляющая. Я даже из мира .NET знаю, что самое популярное — это JSON. Причём сам же его стал массово использовать, как только про него узнал. Зачем мне в .NET с его вездесущим XML понадобился жабоскриптный JSON? Вот поэтому — за простоту и гибкость! Хотя вариантов форматов было море, включая неуклюжий yaml, ini и т.п.

Есть такая штука — инженерное чутьё. Это та самая способность оставаться на месте, когда куча неадекватов бежит сломя голову, чтобы убиться об стену в тупике. Пыль рассеется — сам всё увидишь.
Re: лучшие практики для настроек-конфигов приложения..
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.03.21 12:48
Оценка: +1
Здравствуйте, MadHuman, Вы писали:

MH>Коллеги, поделитесь опытом к каким практикам для организации работы с настройками в приложениях/сервисах пришли и почему..


Мое мнение:

1. Есть настройки для нормальной работы пользователя, и есть "технические" настройки для решения/исследования проблем. Надо их четко различать. К ним даже доступ должен быть разным. Например, в программе с графическим интерфейсом пользовательские настройки следует вынести в меню, а "технические" вполне уместно оставить в конфигурационном файле.

2. Чем пользовательских настроек меньше, тем лучше. Фактически, оставляя пользователю некую настройку, вы создаете механизм, чтобы извлечь из него некую информацию. Не надо пытаться извлекать из пользователя информацию, которой он не обладает, не надо заставлять его принимать решения, на принятие которых у него не хватит квалификации. Многие вещи программа вполне могла бы выяснить для себя автоматически, и не заставлять пользователя делать это за нее.

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

4. В качестве формата лично я предпочитаю .INI. Но это не принципиально.
Re[2]: лучшие практики для настроек-конфигов приложения..
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.03.21 12:50
Оценка: :)
Здравствуйте, hi_octane, Вы писали:

_>Последние несколько моих (наиболее успешных) проектов хранят конфиг в виде C# кода. При старте конфиг компилируется и запускает всё приложение. Основной плюс — раз в квартал надо прямо на проде сделать что-то очень экзотическое, и это всегда получается Основной минус — если в файл "конфига" сможет писать хакер, то полный контроль над системой гарантирован. Но если проект не для масс-маркета и обслуживается персональным админом, этот вариант даёт 200% гибкости.


Получается, для запуска приложения совершенно необходим компилятор, а пользователь должен знать C#?
Re[7]: лучшие практики для настроек-конфигов приложения..
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.03.21 12:59
Оценка: 4 (1) +1 -2
Здравствуйте, Kolesiki, Вы писали:

K>Потому что конфиг — это вообще не про код. Код должен быть в программе, а в конфиге — лишь "настроечные величины". Если ты налепил конфиг в виде кода, ты явно решил задачу левым путём. Времена ЛИСПа прошли и не потому, что ЛИСП устарел — он просто непригоден для надёжного ПО — как раз в силу идеи "данные как код".


1. Времена лиспа не прошли.

2. JS в современном вебе — это данные или код?

3. Идея рассматривать код в качестве данных возникла задолго до лиспа, принадлежит Фон Нейману (это так и называется, "архитектура Фон Неймана), и позволяет использовать для программирования ЭВМ компиляторы, линкеры и загрузчики, а не вводить программы с помощью тумблеров на панели. Революционность этой идеи заключается в том, что в условиях, когда оперативная память была чертовски дорогой и ограниченной в объеме, все равно имело смысл потратить часть ее с целью облегчения жизни программистов, а не "по назначению" — для рассчета баллистических траекторий полета снарядов и взлома вражеских шифров.

4. Если конфигурация должна описывать некие действия (например, куда почтовый сервер должен отправить письмо, в зависимости от его параметров), то описание ее в виде инперативной "программы" может быть значительно удобнее, чем в виде декларативного набора правил.
Re[3]: лучшие практики для настроек-конфигов приложения..
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.03.21 13:02
Оценка:
Здравствуйте, MadHuman, Вы писали:

_>>Последние несколько моих (наиболее успешных) проектов хранят конфиг в виде C# кода.

MH>с моей тз минус — нельзя сделать хот релоад. хотя если поприседать может и можно..

С другой стороны, если твоя система в целом переживает перезапуск какой-то части, то заодно получаешь устойчивость к аварийным перезапускам отдельных компонент. И хот релоад при этом становится не слишком-то и нужным.
Re[3]: лучшие практики для настроек-конфигов приложения..
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.03.21 13:05
Оценка: +1 -1
Здравствуйте, Kolesiki, Вы писали:

K>Это такая 1-апрельская шутка штоле??

K>Эта бредятина документирована на 14(!!!!) страницах. С виду — какой-то гибрид макросов и JSON. На деле — переусложнённая хрень, где в JSON просто вмешали какие-то местечковые задачки. Поверь старому анжанеру — это г****вно не взлетит. Даже hi_octane с его "кодом-как-конфиг" (дырявым донельзя) имеет бóльшие шансы.

Если ты что-то недопонимаешь, это не повод называть "безосновательные". Это повод задуматься: "А не слишком ли я глух к чужим словам, считая своё решение самым правильным?".


http://rsdn.org/forum/dotnet/7979469.1
Автор: Kolesiki
Дата: 28.03.21
Re[3]: лучшие практики для настроек-конфигов приложения..
От: varenikAA  
Дата: 29.03.21 03:27
Оценка: +1
Здравствуйте, Pzz, Вы писали:

Pzz>Получается, для запуска приложения совершенно необходим компилятор, а пользователь должен знать C#?


Уровень знаний у всех разный. Json это тоже часть javascript. Т.е. что-то о программировании нужно знать или нужен UI для изменения настроек.
А это уже совместный доступ. А это уже СУБД. Нужно видимо просто делить настройки на изменяемые и неизменяемые.
Но все условно конечно.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.