Опасности ddos через ping это когда на сервер идут прямые клиентские соединения и их много. Для внутрисерверных соединений ping вполне нормальный механизм. Таймаут можно делать маленький, всё равно под нагрузкой никаких пингов не будет, время считается от момента последней входящей активности.
Если у вас JSON, вам скорее всего не нужен schema registry. Это вообще штука заточенная чисто под avro. Дело в том что это формат сериализации, в котором отсутствуют метаданные. Там нет названий полей как в json или тегов как в protobuf. Это просто бинарно закодированные подряд все поля структуры. И не зная с какой схемой было закодировано сообщение, декодировать его невозможно. Поэтому avro без schema registry существовать практически не может. Выбирая avro надо всегда иметь в виду что все producers и consumers становятся зависимыми от schema registry. И сам он становится критичной частью всей инфраструктуры.
Я немножко не из мира java, но, насколько я представляю, дело обстоит примерно так: клиент имеет свою схему, через registry (регистрируя) он может получить её id. Если id схемы в получаемом сообщении совпадает с клиентской, всё просто. Если нет, клиент запрашивает схему сообщения из registry и если она совместима должен построить конвертер, который декодирует сообщение по старой (или может быть новой) схеме и по правилам эволюции схемы преобразует его в объект текущей схемы.
Абсолютно никак не влияет. Брокеру без разницы что в него кладут, он ничего не проверяет. Schema registry это то, с чем работают клиенты через отдельный api. Оно может быть вообще в другой кафке если что, кафка для этого сервиса просто хранилище. Режимы совместимости в avro просто накладывают ограничения на возможности модификации схем, так чтобы клиент имея локально схему версии X мог декодировать сообщение закодированное со схемой версии Y. Соответственно schema registry при обновлении схемы может такие ограничения проверять и не даст изменить схему если совместимость нарушается.
Ну с variant надо накладные считать, экономит указатель и косвенную адресацию но всегда ест max(sizeof). Ну и таблицы в нем обычно если не boost. А switch я имел в виду именно по Stmt, не по variant, простой перебор всех kind: template<Vis> visit(Stmt&, Vis) ... case If: vis(static_cast<If&>)... Чтобы не писать цепочки if dyn_cast, а использовать перегрузки. Например деструктор без virtual: visit(stmt, (auto& s) { delete &s; });
Есть ещё пара вариантов. Первый это std::variant с автоматическим kind. Второй - написать один шаблонный visit(Stmt&, Visitor) со switch/function table и повыкидывать все цепочки if...else if.
> Легко понять, что умножение 12 на 1 бессмысленно, а скобки вокруг 2 * order не нужны.
Легко заметить что x << n = x * (2^(n+1)). И (x * 1) << n эквивалентно x * (1 << n). А вот вторые скобки обязательны. Чтобы не вспоминать про приоритеты.
Это на основании того что анализируемое значение enum? Частенько использую что то вроде enum class SomeId { null = 0 }. Ну и проверки вроде if(id == SomeId::null) return; Всё за такой проверкой будет считаться unreachable?
А чем не вариант для константных строк использовать string_view? Если она инициализируется литералом, время жизни обеспечено. Можно даже отнаследовать какой нибудь literal_view с constexpr конструктором из массива char.
Насчёт значений по умолчанию для скаляров это грамотное решение. Опциональность приехала из языков с динамической типизацией, где есть null (да и то не для всех это применимо, явный nil например не может быть значением в Lua таблице). И кроме json я что то не припомню форматов кодирования с explicit null значениями. За опциональность надо платить и пусть это будет выражено в явном виде. Мне кажется со стороны Google это был реверанс в сторону C/C++.
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».
RVO начиная с C++17 обязателен.
Опасности ddos через ping это когда на сервер идут прямые клиентские соединения и их много. Для внутрисерверных соединений ping вполне нормальный механизм. Таймаут можно делать маленький, всё равно под нагрузкой никаких пингов не будет, время считается от момента последней входящей активности.
Что за message header и magic byte?
Если у вас JSON, вам скорее всего не нужен schema registry. Это вообще штука заточенная чисто под avro. Дело в том что это формат сериализации, в котором отсутствуют метаданные. Там нет названий полей как в json или тегов как в protobuf. Это просто бинарно закодированные подряд все поля структуры. И не зная с какой схемой было закодировано сообщение, декодировать его невозможно. Поэтому avro без schema registry существовать практически не может. Выбирая avro надо всегда иметь в виду что все producers и consumers становятся зависимыми от schema registry. И сам он становится критичной частью всей инфраструктуры.
Я немножко не из мира java, но, насколько я представляю, дело обстоит примерно так: клиент имеет свою схему, через registry (регистрируя) он может получить её id. Если id схемы в получаемом сообщении совпадает с клиентской, всё просто. Если нет, клиент запрашивает схему сообщения из registry и если она совместима должен построить конвертер, который декодирует сообщение по старой (или может быть новой) схеме и по правилам эволюции схемы преобразует его в объект текущей схемы.
Абсолютно никак не влияет. Брокеру без разницы что в него кладут, он ничего не проверяет. Schema registry это то, с чем работают клиенты через отдельный api. Оно может быть вообще в другой кафке если что, кафка для этого сервиса просто хранилище. Режимы совместимости в avro просто накладывают ограничения на возможности модификации схем, так чтобы клиент имея локально схему версии X мог декодировать сообщение закодированное со схемой версии Y. Соответственно schema registry при обновлении схемы может такие ограничения проверять и не даст изменить схему если совместимость нарушается.
Упс, пардон, это перевод...
4 миллиарда по 100 байт это примерно 400 гигабайт в минуту. Умножаем на 8, делим на 60. Это канал в 53 гигабита. Что за железо?
Ну с variant надо накладные считать, экономит указатель и косвенную адресацию но всегда ест max(sizeof). Ну и таблицы в нем обычно если не boost. А switch я имел в виду именно по Stmt, не по variant, простой перебор всех kind: template<Vis> visit(Stmt&, Vis) ... case If: vis(static_cast<If&>)... Чтобы не писать цепочки if dyn_cast, а использовать перегрузки. Например деструктор без virtual: visit(stmt, (auto& s) { delete &s; });
Есть ещё пара вариантов. Первый это std::variant с автоматическим kind. Второй - написать один шаблонный visit(Stmt&, Visitor) со switch/function table и повыкидывать все цепочки if...else if.
Легко заметить что x << n = x * (2^(n+1)). И (x * 1) << n эквивалентно x * (1 << n). А вот вторые скобки обязательны. Чтобы не вспоминать про приоритеты.
В примере с рефакторингом через switch последние две строки просто переходят в default ветку. И перестают считаться unreachable.
Но там же if/elsif/elsif. Ветки else нет. Судить о недостижимом можно только по тому что в этих ветках проверены все значения enum.
Это на основании того что анализируемое значение enum? Частенько использую что то вроде enum class SomeId { null = 0 }. Ну и проверки вроде if(id == SomeId::null) return; Всё за такой проверкой будет считаться unreachable?
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 выполнение которой в общем случае не может быть гарантировано. Например в случае возникновения ошибки внутри самой операции.
И именно об этом и пишется в статье — «can guarantee that updates to state managed by the SPE are committed only once to a durable backend store».