Dispatch a read-only KV operation. Routes through the gateway when available (cluster-aware routing), falling back to direct local SPSC dispatch on single-node boot. Bridge/dispatch errors are mapped to `Error::Bridge` with a `BUSY` detail so the RESP handler can return `-BUSY` to the Redis client.
(
state: &SharedState,
session: &RespSession,
plan: PhysicalPlan,
)
| 27 | /// Bridge/dispatch errors are mapped to `Error::Bridge` with a `BUSY` detail |
| 28 | /// so the RESP handler can return `-BUSY` to the Redis client. |
| 29 | pub(super) async fn dispatch_kv( |
| 30 | state: &SharedState, |
| 31 | session: &RespSession, |
| 32 | plan: PhysicalPlan, |
| 33 | ) -> crate::Result<Response> { |
| 34 | match state.gateway.as_ref() { |
| 35 | Some(gw) => { |
| 36 | let gw_ctx = QueryContext { |
| 37 | tenant_id: session.tenant_id, |
| 38 | trace_id: TraceId::generate(), |
| 39 | database_id: DatabaseId::DEFAULT, |
| 40 | }; |
| 41 | gw.execute(&gw_ctx, plan) |
| 42 | .await |
| 43 | .map_err(|e| crate::Error::Bridge { |
| 44 | detail: GatewayErrorMap::to_resp(&e), |
| 45 | }) |
| 46 | .map(gateway_payloads_to_response) |
| 47 | } |
| 48 | None => { |
| 49 | let vshard = |
| 50 | VShardId::from_collection_in_database(DatabaseId::DEFAULT, &session.collection); |
| 51 | dispatch_utils::dispatch_to_data_plane( |
| 52 | state, |
| 53 | session.tenant_id, |
| 54 | vshard, |
| 55 | plan, |
| 56 | TraceId::ZERO, |
| 57 | ) |
| 58 | .await |
| 59 | .map_err(map_busy_error) |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | /// Dispatch a KV write operation: WAL append first, then gateway or Data Plane. |
| 65 | /// |
no test coverage detected