Send a distinct payload to each shard and collect responses. `per_shard` — `(vshard_id, payload_bytes)` pairs, one per target shard. Returns `(shard_id, response_payload_bytes)` in arrival order.
(
params: &FanOutPartitionedParams,
opcode: u32,
per_shard: &[(u32, Vec<u8>)],
dispatch: &Arc<dyn ShardRpcDispatch>,
circuit_breaker: &CircuitBreaker,
)
| 166 | /// `per_shard` — `(vshard_id, payload_bytes)` pairs, one per target shard. |
| 167 | /// Returns `(shard_id, response_payload_bytes)` in arrival order. |
| 168 | pub async fn fan_out_partitioned( |
| 169 | params: &FanOutPartitionedParams, |
| 170 | opcode: u32, |
| 171 | per_shard: &[(u32, Vec<u8>)], |
| 172 | dispatch: &Arc<dyn ShardRpcDispatch>, |
| 173 | circuit_breaker: &CircuitBreaker, |
| 174 | ) -> Result<Vec<(u32, Vec<u8>)>> { |
| 175 | if per_shard.is_empty() { |
| 176 | return Ok(Vec::new()); |
| 177 | } |
| 178 | |
| 179 | let mut futs = futures::stream::FuturesUnordered::new(); |
| 180 | |
| 181 | for (shard_id, payload) in per_shard { |
| 182 | circuit_breaker.check(*shard_id as u64)?; |
| 183 | |
| 184 | let env = VShardEnvelope::new( |
| 185 | msg_type_from_opcode(opcode)?, |
| 186 | params.source_node, |
| 187 | 0, |
| 188 | *shard_id, |
| 189 | payload.clone(), |
| 190 | ); |
| 191 | let timeout_ms = params.timeout_ms; |
| 192 | let dispatch = Arc::clone(dispatch); |
| 193 | let cb_shard = *shard_id; |
| 194 | |
| 195 | futs.push(async move { |
| 196 | match call_with_wrong_owner_retry(&dispatch, env, timeout_ms).await { |
| 197 | Ok(resp) => Ok((cb_shard, resp.payload)), |
| 198 | Err(e) => Err((cb_shard, e)), |
| 199 | } |
| 200 | }); |
| 201 | } |
| 202 | |
| 203 | let mut results = Vec::with_capacity(per_shard.len()); |
| 204 | while let Some(outcome) = futs.next().await { |
| 205 | match outcome { |
| 206 | Ok((shard_id, payload)) => { |
| 207 | circuit_breaker.record_success(shard_id as u64); |
| 208 | results.push((shard_id, payload)); |
| 209 | } |
| 210 | Err((shard_id, e)) => { |
| 211 | circuit_breaker.record_failure(shard_id as u64); |
| 212 | return Err(e); |
| 213 | } |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | Ok(results) |
| 218 | } |
| 219 | |
| 220 | /// Map an opcode constant to a `VShardMessageType`. |
| 221 | /// |
no test coverage detected