Skip to content

Commit

Permalink
producer/request_state: make set_value() idempotent
Browse files Browse the repository at this point in the history
In some racy situations it may happen that the request is already
errored out. Consider the following sequence of actions.

replicate_f - succeeded but set_value() not called
-- scheduling point --
term change -> sync() -> GC of inflight requests, request is marked
timedout

now set_value() is called in the original fiber, this triggers an
assert.

Relaxing the assert condition to make it idempotent. Subsequent client
retry of the request will be marked success (once the change is applied
in the stm and the request state is populated).

Unable to reproduce in a unit test mainly due to lack of an idempotent
client in the unit test fixture.
  • Loading branch information
bharathv committed Aug 5, 2024
1 parent a39076d commit a2f2f07
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions src/v/cluster/producer_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ result_promise_t::future_type request::result() const {
}

void request::set_value(request_result_t::value_type value) {
vassert(
_state <= request_state::in_progress && !_result.available(),
"unexpected request state during result set: {}",
*this);
_result.set_value(value);
_state = request_state::completed;
if (_state != request_state::completed) {
_result.set_value(value);
_state = request_state::completed;
}
}

void request::set_error(request_result_t::error_type error) {
Expand Down

0 comments on commit a2f2f07

Please sign in to comment.