krishvishal opened a new pull request, #3553:
URL: https://github.com/apache/iggy/pull/3553
## Why
`server-ng` previously validated metadata business rules during
**preflight**: primary-only, before replication. Invalid requests were then
silently dropped.
This caused two issues:
**1. VSR correctness.** A rejection must be a deterministic function of the
committed log. It should be computed during apply on every replica and recorded
so that all replicas agree. Preflight validation uses a primary-local snapshot,
and its verdict is never replicated. After a view change, the new primary is
not guaranteed to reach the same decision.
**2. Infinite retry.** The in-process path mapped the preflight `Err` to
`Canceled`, leaving the home shard silent. As a result, the SDK kept retrying
permanently invalid requests forever, such as `CreatePartitions` on a missing
topic.
## What Changed
**Result taxonomy.** Added `core/metadata/src/stm/result.rs`. There is now
one closed `#[repr(u32)]` enum per operation: `Ok = 0`, with other
discriminants reused from the existing `IggyError` code space. This keeps SDK
error mapping compatible with existing codes.
**Apply now returns committed results.** `StateHandler::apply` now returns
`ApplyReply { code, body }` instead of `Bytes`. Every previous silent
`Bytes::new()` no-op is now represented as a committed result code.
`MuxStateMachine::update` now reserves `Err` for decode/corruption failures
only.
**Result is encoded in the reply body.** The result rides in the reply body.
The reply body now starts with a sparse result section, `[count][index,
result]*`, followed by the payload. This is written in place via
`build_reply_message_with`, using one allocation and one payload copy. There is
no `ReplyHeader` layout change.
**Eviction instead of silent drop.** Structurally invalid requests are now
evicted rather than silently dropped: `not-client-allowed` maps to
`InvalidRequestOperation`, while undecodable/overflow maps to
`InvalidRequestBody`.
**Removed preflight partition-count read.** Deleted the
`current_partition_count` preflight read. Parent existence is now checked at
commit time and returned as `CreatePartitionsResult::{Stream, Topic}NotFound`,
removing the TOCTOU window.
**Consensus frame size floor.** Every consensus frame’s `size` must now span
its header. This is asserted during `consensus_message` construction,
`PrepareOk` projection, and in the simulator. This prevents reply-body slicing
from underflowing.
**Simulator changes.** The simulator now uses outcome-first generation:
operations target a chosen outcome, including error outcomes; `on_reply`
decodes the committed code from the body; and the decoded code is asserted to
be a declared result code. The strict targeted-equals-committed oracle is gated
to serial runs only: `client_count == 1 && CLIENT_REQUEST_QUEUE_MAX == 1`.
## Wire / SDK Impact
`ReplyHeader` is unchanged. This is not a `#[repr(C)]` layout change.
However, the **reply body format changes**. A result section now precedes the
payload, so body decoding changes for success replies as well. There is no
released `server-ng` wire format to break.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]