Обновить
1
0
Соколов Дмитрий@bibmaster

Разработчик

Отправить сообщение
Print не очень показательный. Пусть результат будет например сохраняемый в бд счётчик событий. Обеспечить идемпотентность может только фиксация факта учёта и увеличения счётчика в одной транзакции. Причём брокер действительно не может принципиально обеспечить exactly once. Он может предоставить возможность фиксации факта обработки. Но выборка события, обработка и фиксация обработки разнесены во времени. Так что даже в этом случае exactly once в случае ошибок превращается в at least once.
Хотел бы я увидеть реализацию без коммита, т.е. без лога транзакций которая тот же print id сделает exactly once.
Да, мне кажется Врунгель у Виктора Боковни более точно соответствует книжному образу.
В русском языке повелительное наклонение принимает форму заклинания, наговора, усиливающего вносимое изменение, — «Исправь то», «Сделай сё». А вместо точки в конце лучше ставить 'X', — «скрестить пальцы».
Как-то тоже встала задача вписать в 64 бита и дроби десятичные и целые. Отдал под экспоненту 1 бит, младший. Либо 0 либо -6. И сверху всё в операциях ограничил 18 десятичными разрядами. Т.е. если по модулю число < 10^12, то 6 знаков после запятой без потерь. Если больше, дробная часть откидывается и число может достигать значения до 10^18. 18 десятичных разрядов влезают в 60 бит, т.е. за вычетом знака есть ещё пара битов про запас. И это тоже оказалось полезным. Для сериализации сложил знак и экспоненту в младшие 4 бита, остальное, соответственно мантисса. И всё это добро всё ещё вписывается в 64 бита, т.е. может быть достаточно компактно закодировано например в 7 битный protobuf uint64.
Да, по описанию всё так, только не работало. Оказывается починили в gcc 4.9:
It is now possible to call x86 intrinsics from select functions in a file that are tagged with the corresponding target attribute without having to compile the entire file with the -mxxx option. This improves the usability of x86 intrinsics and is particularly useful when doing Function Multiversioning.
С intrinsics ещё такая штука, если поддержку того или иного instruction set надо проверять в runtime, приходится generic/optimized версии функций компилировать отдельно. Или же можно использовать явный вызов через asm. Кстати, о SSE… Не зря например в протоколе Kafka используют CRC32C. Потому что для него есть инструкции в SSE4.2.
Причем все файлы можно оставить в проекте, отключая компиляцию через свойство HEADER_FILE_ONLY.
Unity build можно делать вручную, без автогенерации. У нас например сделано так — Cmake функции передается список исходников, в которых она ищет файлы вида unity_build.*.cpp. Из этих файлов извлекается список include и в зависимости от опции в сборке либо отключается сам unity build модуль либо все его включения.
Кстати, интерфейс аллокатора общего назначения уже есть в стандарте: en.cppreference.com/w/cpp/memory/memory_resource
Если слова заменяются целиком, возможно hash словарь замен будет быстрее.
Да даже литералы строковые лучше заворачивать в string_view, конструктор от указателя у них constexpr (спасибо char_traits), так что с временем инициализации то же самое, зато гарантирует что strlen более не понадобится (даже для extern литералов). Ещё прекрасный пример, кэширование каких то структур где строки имеют большую вероятность повтора, просто собрать все в какой то словарь (unordered_set) и хранить в виде string_view.
На самом деле в c++ c_str практически нигде не нужен. Даже в тех местах где он нужен для передачи в C функции можно на входе принять string_view и написать небольшой checker, который, если нуля не будет, скинет всё в буферную строку и добавит его. Тогда заменив все параметры на string_view можно будет упоминание c_str в коде подозревать в преждевременной пессимизации.
Это не мешает посмотреть как там сделан этот helper. Точно так же формируется строка и передается сервису. Опять таки как правильно написать макрос условный, хотя есть и более красивый на мой взгляд вариант вместо for.
Потоковый wrapper c push message в деструкторе, см. boost logger, там же поверх навороты для автоматических атрибутов и завернутый в макросы анализ severity.
Вообще в этом плане отлично сделан squash merge на github. Для bitbucket например это соответствует стратегии squash forward only. Но в отличие от github при этом генерируется монструозный комментарий из всех squashed commits и отредактировать его нельзя, разве что в хвост что-то добавить, поэтому предпочтительней всё таки ручной rebase.
Ну и для чистоты истории (требование один коммит на pr) собрать все эти коммиты в кучу через interactive rebase перед оформлением pr вообще не проблема.
Это локальная ветка разработчика, волен творить там что угодно. Она вообще в его личном fork'е может жить если уж на то пошло. Ну и удобно, на работе push, дома fetch, зачем что то выдумывать когда есть git?
Разработчик может делать commit и push просто при окончании рабочего дня. На всякий случай, а вдруг пожар… И конечно такие commit'ы могут быть нерабочими (не дописал слово, но смена закончена). Слияние такой ветки через merge навеки вписывает всю эту кучу-малу в историю master commit'а. Потому используем стратегию слияния ff-only плюс требование один commit на один pr. Т.е. перед созданием pr всегда нужно делать rebase. Требование одного commit'а гарантирует отсутствие промежуточных кривых версий в master ветке.
Есть более дешёвый, но не стандартизованный intrusive_ptr. Но, конечно же без weak указателей. Странно что в boost не заточили на работу с такими указателям семейство intrusive контейнеров. В совокупности они хороши.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность