Repository navigation
3/6: Async IDC Receiver side. - #6150
Shubham8287 wants to merge 8 commits into
Conversation
2d47c10 to
f2f6ac8
Compare
dd953a3 to
0bdb12c
Compare
|
|
||
| // A duplicate delivery replays the stored outcome without rerunning the reducer. | ||
| call_idc(Identity::ONE, 1, false, signature_hash, StatusCode::OK, "").await; | ||
| assert_counts(2, 1, 2).await; |
There was a problem hiding this comment.
Should we skip lifecycle reducers when we’re not running the actual reducer again? But then, couldn’t updated module logic reject an identity that was previously allowed? So, I may keep it like this
57c54ee to
3d147a6
Compare
3d147a6 to
6864735
Compare
| let (tx, decision) = checked.map_err(DBError::from)?; | ||
| // Commit the acknowledgment cleanup even if this delivery cannot execute. | ||
| let (tx_offset, tx_data, tx_metrics, reducer) = stdb | ||
| .commit_tx(tx)? |
There was a problem hiding this comment.
The check and the execution need to be atomic in order to maintain exactly once semantics on the receiver side, no? That is, we should run them in the same transaction.
There was a problem hiding this comment.
It relies on the UniqueConstraintVoilation and the Existed check in record_inbound_idc_outcome for exactly-once semantics. During a race, one of the transactions will fail in record_inbound_idc_outcome.
To make it more explicit, I will lift the checks out of record_inbound_idc_outcome and do it in same tx before executing reducer to fail early. Does it makes sense?
There was a problem hiding this comment.
I pushed a commit, so that we do checking against st_* tables within a reducer or fallback tx.
| let tx = stdb.begin_mut_tx(IsolationLevel::Serializable, Workload::Internal); | ||
| let (tx, ()) = stdb | ||
| .with_auto_rollback(tx, |tx| { | ||
| tx.record_inbound_idc_outcome(sender_identity, stream_id, seq, status, payload.clone()) | ||
| }) |
There was a problem hiding this comment.
Similarly here, because recording a failure needs a separate transaction, don't we need to check if an outcome for this attempt was already recorded before trying to record the failure?
bb1fdec to
c5e3589
Compare
Description of Changes
This PR builds the receiver side of async IDC, it contains 3 commits and can be reviewed accordingly:
Reducer signature hashing
Adds a canonical IDC reducer signature hash, receiver checks this hash before decoding positional BSATN arguments. This prevents an old sender from accidentally calling a reducer after the receiver has changed the reducer signature.
Host-signed IDC authentication
Adds IDC-specific database credentials signed by the host key.
The IDC route authenticates the sending database separately from normal client auth. The module sees
ctx.senderas the sending database identity, but it does not receive a client JWT. This keeps IDC transportcredentials out of module-visible auth state.
Durable receiver outcomes
Adds the authenticated
call-from-databasereceiver path.The receiver tracks ordered IDC streams with
stream_idandseq, records terminal outcomes durably, replaysalready-decided outcomes on retry, and rejects out-of-order messages with a retryable response. Successful
reducer effects and the receiver-side IDC outcome are committed atomically; terminal failures are recorded as
durable outcomes so the stream can continue.
Proposal Drift
API and ABI breaking changes
NA, additive API.
Rollback safety impact
n/a
Expected complexity level and risk
3
Testing
unit and integration tests.