fix(ecstore): heap-allocate durable ILM receipt futures (#6527)

PR #6369 awaits record_durable_ilm_decommission_progress/terminal inline
from save/delete_transition_transaction_record. Their state machines are
large and sit on the already-deep transition worker poll chain
(worker -> transition -> transaction record -> delete_config -> full
store delete fanout), which overflowed the default 2 MiB tokio worker
stack in debug builds: app::lifecycle_transition_api_test::
compensation_driven_complete_multipart_upload_still_transitions died
with SIGABRT in under a second (first-bad commit via git bisect
1.0.0-rc.3..1ec1a8d90: 34bbc1adb, #6369).

41546dee5 already unblocked the test by moving it onto a dedicated
32 MiB thread; this change removes the underlying stack growth so every
caller of the transaction-record helpers keeps its previous headroom.
With it, the test also passes on a plain 2 MiB tokio worker.
This commit is contained in:
唐小鸭
2026-08-24 20:38:46 +08:00
committed by GitHub
parent e4dfc6f45b
commit 3d75e7b51f
@@ -586,7 +586,10 @@ pub(crate) async fn save_transition_transaction_record(
transition_transaction_record_object_name(transaction.transaction_id).map_err(transition_transaction_store_error)?;
let data = transaction.encode().map_err(transition_transaction_store_error)?;
config_boundary::save_config(api.clone(), &object, data.clone()).await?;
api.record_durable_ilm_decommission_progress(&object, &data).await
// Box::pin: the durable-receipt state machine is large and sits on the
// already-deep transition worker poll chain; keeping it inline overflows
// the default 2 MiB tokio worker stack in debug builds.
Box::pin(api.record_durable_ilm_decommission_progress(&object, &data)).await
}
pub(crate) async fn load_transition_transaction_record(
@@ -605,7 +608,8 @@ pub(crate) async fn delete_transition_transaction_record(
let object =
transition_transaction_record_object_name(transaction.transaction_id).map_err(transition_transaction_store_error)?;
let data = transaction.encode().map_err(transition_transaction_store_error)?;
api.record_durable_ilm_decommission_terminal(&object, &data).await?;
// Box::pin: see save_transition_transaction_record.
Box::pin(api.record_durable_ilm_decommission_terminal(&object, &data)).await?;
match config_boundary::delete_config(api, &object).await {
Ok(()) | Err(Error::ConfigNotFound) => Ok(()),
Err(err) => Err(err),