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

Разработчик

Отправить сообщение
ASN.1 BER/DER. BSON. Avro. Thrift. Bycycle в конце концов.
Насчёт значений по умолчанию для скаляров это грамотное решение. Опциональность приехала из языков с динамической типизацией, где есть null (да и то не для всех это применимо, явный nil например не может быть значением в Lua таблице). И кроме json я что то не припомню форматов кодирования с explicit null значениями. За опциональность надо платить и пусть это будет выражено в явном виде. Мне кажется со стороны Google это был реверанс в сторону C/C++.
Используя «псеко»… :)

1 подход.
commit_snapshot(snapshot 1)
log_and_apply_transaction(snapshot 2, transaction)
log_and_apply_transaction(snapshot 2, transaction)
...
log_and_apply_transaction(snapshot 2, transaction)
commit_snapshot(snapshot 2)
...

restore:
rollback_all_transactions_since_last_commited_snapshot()
reply_all_transactions_since_last_commited_snapshot()

2 подход.
tx.open()
if tx.log_transaction(transaction.id): apply_transaction(transaction)
tx.commit()

restore: not required, all updates idempotent


Различия в том, что в первом случае лог можно писать только в рамках текущего окна событий. При этом в upstream периодически закидываются пинги, сигналы commit snapshot. О консистентности системы в целом можно судить по min(last commited snapshot) в sink.

А пример с print id автор приводит как раз в контексте того что print как user defined logic — не транзакционная операция, т.е. операция, exactly once выполнение которой в общем случае не может быть гарантировано. Например в случае возникновения ошибки внутри самой операции.
Смешались в кучу кони люди… Какой lock-free если в конце концов всё равно «теперь осталось лишь добавить взаимодействие с базой данных… tx.open()… tx.commit()».
И именно об этом и пишется в статье — «can guarantee that updates to state managed by the SPE are committed only once to a durable backend store».
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.

Информация

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