Pull to refresh
20
0
Андрей Владиславович Галкин @andvgal

Свободный художник на все руки

Send message
Проблема в том, что формально были сделаны юниты для сервисов в рамках официального перехода на systemd, но по факту они не поддерживают полный набор возможностей старых SysV скриптов, что далеко не всегда очевидно и надо перепроверять все нестандартные фичи самостоятельно.

Пожалуй сразу могу вспомнить проблему с BIND9, открытую ещё в прошлом ноябре. При этом некоторые опции, такие как chroot задаются при запуске.
Обновление GlusterFS с 3.2 до 3.5 очень нетривиально.
Из-за сложившейся ситуации со смесью Jessie и Wheezy в инфраструктуре и сопутствующими проблемами с унифицированными конфигурациями puppet, пришлось идти на риск и поэтапно обновлять всю инфраструктуру во время выхода Jessie RC1.

От systemd всё же пришлось отказаться и вернуться к SysV. Лишь несколько примеров. От греха подальше, сильно расширят список на своей шкуре не захотелось.
  • дополнительные конфигурации сервисов из /etc/default не поддерживаются. Самое печальное, что это не всегда можно сразу понять.
  • многие дополнительные пакеты не из стандартных репозиториев просто не systemd-aware или лучше бы и не добавляли поддержки в том виде, что сделали
  • Percona XtraDB Cluster казалось бы работал, но когда дело дошло до тестирования восстановления узла с нуля на боевой БД systemd так постарался с управлением, что весь кластер ошарашило и заклинило

Обновление Ruby до 2.1. В релизе какой-то snapshot Redmine 3.0-preX. Redmine 3.0 не работает из-за слишком новых зависимостей. В общем, привет RVM.

Так же в релиз не вошли многие важные пакеты — их нужно доставлять из testing/sid с правильным pinning. Рудименты от wheezy могут перестать работать. В частности проблема возникла в связке corosync+pacemaker, где вылезали undefined symbols.

Что-то многое ещё, но сразу не скажу, т.к. прелести от обновления вкушали ещё далеко не одну неделю после.

Есть и приятные моменты:
  • обновление Xen c 4.1 до 4.4 с новым эффективным режимом PVH. Честно сказать, PVHVM вдруг почему-то перестал работать непосредственно после последнего обновления ядра перед официальным релизом и было быстрее перейти на более эффективный PVH, чем разбираться
  • хоть и был в wheezy-backports, но формально nginx обновился с 1.2.x до 1.6.x
  • puppet обновился до крайней версии и не требует дополнительных репозиториев [со сломанными конфигами по умолчанию]
  • наконец-то установка полнофункционально работает из коробки как на стационарных, так и на портативных компьютерах (KDE) без потребности доводить до ума конфигурационные файлы вручную, non-free firmware лучше заранее закинуть на флэшечку. Тут systemd показывает себя во всей красе в хорошем смысле. UEFI тоже работает из коробки и поддерживается при установке ещё с Wheezy. Сильно рекомендую поставить систему с нуля, а не обновляться.
  • Формально Node.js/npm появился в пакетах в ± пригодном состоянии для использования, но как мёртвому припарки
Это было сказано в контексте приложений… К сожалению, стандартная библиотека C и интерфейс POSIX есть какой есть. Их можно любить, можно ненавидеть.
Вот тогда и начинаем мракобесие с макросами.

Если же С++, то эту кухню можно спрятать в member function union'а, поскольку без выполнения определённых условий union остаётся POD-типом данных. Для всего прочего притянуть template и поставить на поток…

Фантазия может улететь далеко, но в С++ для решения той же задачи есть exceptions, а в C — thread safe errno.
Поэтому, я принципиально против таких интерфейсов.
Соглашусь, но вы ведь не программируете бизнес логику полагаясь на теорию вероятностей? Оптимизация — да, но не контроль ошибок.

При этом в любом случае надо создавать отдельный тип, который ЧЁТКО указывает, что вместо указателя может быть возращено мракобесие.

Пример:
struct MyType;
typedef struct MyType *MyTypeOrError;


Ну, а лучше вообще union:

union MyTypeOrError {
    struct MyType *my_type;
    ErrorCode error_code;
};

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

Единственное, что можно извлечь в userland — это проверку на IS_NULL (от 0 до N), где N — какое-то условное значение, при условии, что программа чётко знает, что в этом промежутке нет области данных (с любыми правами доступа). Такую гарантию можно дать только зная скрипт линковщика, и то, если не допустимы перемещения.

Какой смысл? Очень часто бывает, что возвращают адрес смещения поля в структуре, что не проходит проверку на ноль, если сам указатель структуры был нулевой и поле не первое. Обращения по таким адресам на некоторых архитектурах вообще вызывает машинные прерывания с интересными последствиями.
Есть опыт работы с конкурентом, которого вы должны хорошо знать, в рамках Embedded Linux по требованиям PCI-DSS v4 (да, на сайте пока только v3). Конкурента выбирали долго, сравнивая практически все возможные открытые и коммерческие предложения.

У них всё стекается на общий сервер с ± вменяемым веб-фронтендом и десктопным клиентом. Соответственно разработчики могут делать свои потоки для рабочих билдов, а так же билд-сервера могут пихать в потоки для каждой стабильной ветки проекта. При первом проходе, у нас нашлось около 9K проблем, включая малозначительные. Хватило менее недели коллективных усилий архитекторов чтобы рассортировать ложные срабатывания. Если бы мы возились с файлами, а не централизованной базой с удобным интерфейсом, это определённо заняло бы больше времени. При повторных проходах система сама определяет встречалась ли та же самая проблема, либо появилась новая.

Система была достаточно умной чтобы связывать проблемы на разных потоках. Т. е. не нужно рассортировывать заново всё для каждой новой стабильной ветки проекта или не воспроизводимых локальных сборок — новые проблемы были сразу видны.

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

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

Для тех, кто будет скоро обновляться с Debian wheezy до jessie с выходом последнего, будьте бдительны: GlusterFS 3.2 нельзя обновить до 3.5 «просто так».

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

Мой личный опыт около 7 лет — это постепенная трансформация более десятка клонированных проектов. написанный как бы на C, но фактически имеющих под собой прототип ASM Z80 кода, «переведённого» в лоб. Полный стек над операционной системой, включая тонны бесполезных и устаревших комментариев, занимал порядка 700 тыс. строк кода для каждого из них, если мне не изменяет память. К общей проблеме ещё добавился неудержимый копипаст предшественников, который на практики не давал возможности сформировать хоть какие-то библиотеки повторно используемого кода, не говоря уже об условной компиляции под разные модели.

Подход был примерно следующий:
  • Включение максимально количество проверок предупреждений и ошибок компиляции
  • Включение превращения предупреждений компиляции в ошибки
  • Отключение предыдущего пункта для предупреждений, которые сложно исправить быстро, но чтобы мозолило глаза всем
  • То же самое, но для линковки
  • Полный переход на компиляцию как C++, не меняя расширения файлов чтобы не создавать проблем команде из около 15 человек, активно работающих над проектами и сливающих изменения из одного в другой
    • Даёт возможность вызывать С++ без extern «C» обёрток
    • Значительно более серьёзный контроль типов, позволяющий выявить скрытые логические ошибки
    • Жёсткий контроль прототипов функций при линковке — тоже можно много нового открыть о проекте
  • Использование регулярных выражений для «исправления» кода чтобы избежать многочасовой обезьяньей работы
  • Поэтапное выявления схожих частей, унификация с переписыванием на C++ (в большинстве случаев с нуля без отсылок к оригинальному коду) и вынесение в общую библиотеку в течение всего времени. Т.е. от одной стабильной ветки до другой было достаточно мало изменений чтобы можно было покрыть в QA за разумное время
  • Всё делается поэтапно в режиме Continuous Integration — иначе гарантировано будут проблемы со сливанием, которые не будут замечены в тысячах файлов изменений
  • Общая зачистка кода от локальных переменных модулей, раскопированных объявлений типов и функций, покрытие автоматическими тестами и т.п.
  • Полное выпиливание условной компиляции с заменой на модули/плагины и/или мета-программирование на шаблонах
  • Анализ и оптимизация по скорости, размеру и потреблению питания (проекты для встроенных систем — POS)
  • Чтобы научить команду думать в «правильном» ООП мышлении, научить специфичным «трюкам» и использовать хороший стиль (но не только поэтому), все изменения проходили проверку прямо по рабочему месту перед коммитами. Ветки создавались только для заданий, требующих более двух дней разработки или по желанию разработчика (объём изменений, сложная отладка, и т.п.)
  • Переход на CMake. Собственная, оптимизированная по скорости работы, сборка инструментов для разработки. Общее сокращение время полной сборки с 35-40 до менее 3 минут. Реализация правильной thread model библиотеки для встроенной операционки
  • Явно много ещё чего-то, о чём так быстро не вспомню
Мог пропустить комментарий, где эта версия уже выдвигалась:
… как надежное хранилище файлов, с использованием криптостойкого алгоритма AES256 FIPS140-2 Level 3.


Если не подделка, то вполне возможен подлог (или нашли лазейку регламента) для сертификации со стороны производителя. Софтверное решение действительно дешевле разработать и отладить, чем полноценную железку. А BOM (Bill of Materials) всего-лишь формальное прикрытие — поэтому и потратились.
Я не берусь быть истиной в последней инстанции, но большинство из существующих подходов:
  • узкоспециализированы и наполнены специфичным программным интерфейсов определённой среды исполнения
  • и/или скудны на обработку ошибок исполнения и инструменты отладки
  • и/или в принципе, могут отразить лишь определённеый кусок кода, больше ориентированы прятать громоздкую логику под капот
  • и/или в принципе, не предусмотрено понятие ограничения по времени и отмены задачи
  • и/или отсутствие какого-то централизованного представления о задаче — всё размазано по локальным переменным
  • и/или слабо контролируют правильность использование инструмента
  • и/или не представляют концепции написания интерфейса библиотек, которые внутри задают собственные шаги выполнения


Моей целью было сделать инструмент, с помощью которого можно в буквально смысле перенести «синхронный» (последовательный) код в асинхронную среду исполнения.

Возьмём типовой пример бизнес логики:
Создаётся рабочий поток (worker thread), который в цикле обрабатывает поступающие запросы:
1. Устанавливается общее ограничение по времени на обработку одного запроса
2. Обрабатываются входные данные
3. Происходят вызовы в другие системы, каждый со своим ограничением по времени
4. Происходят сравнительно тривиальные вычисления (сложные подразумевают оформление в виде библиотеки со всем вытекающим из этого)
5. Формируются и отсылаются выходные данные

Альтернативно 1:
* Кидается исключение, которое не перехватывается бизнес-логикой
* Освобождаются все ресурсы, связанные с данным запросом
* Ловится исключение и формируется ответ-ошибка

Альтернативно 2:
* Срабатывает ограничение по времени исполнения
* Задача отменяется
* Освобождаются все ресурсы
* Формируется ответ-ошибка


FutoIn AsyncSteps именно и был реализовано как аналогия рабочего потока (точнее даже «лёгкого» потока), который можно реализовать на широко распространённых языках программирования.

Хочу ещё раз отметить, что AsyncSteps — это не самоцель, а концепция решения проблемы написания унифицированного по структуре кода бизнес-логики на разных языках программирования.
Проблема ставится другой концепцией, которая решается в рамках другого проекта: как написать легко масштабируемое асинхронное приложение с повторно используемым кодом, чётко оформленным в компоненты, используя разные технологии разработки. Пример: сначала написать прототип на JavaScript/Python, а потом только отдельные части оптимизировать/сделать более надёжными/развить на Java, C++ или C# без шаманства с «кодом-клеем» или вообще переписыванием уже отлаженных компонентов.
У меня такое впечатление, что пока никто не задавался вопросом как серьёзную бизнес-логику, вроде финансовых транзакций реального времени перенести на асинхронные рельсы.
Либо кто-то об этом задумывался, но разобравшись в проблеме и осознав сколько граблей можно собрать, просто забыл эту идея как страшный сон.
Концентрация идёт на бизнес-логику, а не «тактические» подходы как подождать и обработать внешнее событие. Скажем так, другая крайность.

1. Исходную синхронную бизнес-логику можно сравнивать практически diff'ом, игнорируя отступы, после конвертации
2. AsyncSteps объект задаёт своего рода задачу — а-ля асинхронный поток обработки.
2.1. Без лишних проблем можно гарантированно ограничить общее время исполнение шага и всех вложенных шагов просто вызвав as.setTimeout()
2.2. При надобности всю задачу можно аннулировать, не беспокоясь о проблемах освобождения внешних ресурсов, т.к. каждый шаг позволяет установить обработчик отмены
3. Есть возможность хранить переменные состояния. Пример: при получении запроса, можно сохранить всю мета-информацию о нём для дальнейшего использования (отладка, авторизация, логирование т.п.)

Разумеется, основное применение всё же на стороне сервисов, а не в пользовательском интерфейсе. При этом, ни что не мешает использовать тот же Reactive вместе с AsyncSteps (пример внешнего события).

P.S. Я ни в коем случае вас не порицаю, если вам удобнее писать что-то вроде:

function do_try(){
    call_library();
}

function do_catch( err ){
    // handle error
}

try {
    do_try();
} catch( e ) {
    do_catch( e );
}
12 ...
19

Information

Rating
Does not participate
Location
Рига, Латвия, Латвия
Registered
Activity