Store a key-value pair with strong consistency. # Errors Returns an error if the node is not the leader, the channel is closed, the operation times out, or the state machine returns a server error.
(
&self,
key: impl AsRef<[u8]>,
value: impl AsRef<[u8]>,
)
| 179 | /// Returns an error if the node is not the leader, the channel is closed, |
| 180 | /// the operation times out, or the state machine returns a server error. |
| 181 | pub async fn put( |
| 182 | &self, |
| 183 | key: impl AsRef<[u8]>, |
| 184 | value: impl AsRef<[u8]>, |
| 185 | ) -> ClientApiResult<()> { |
| 186 | let request = ClientWriteRequest { |
| 187 | client_id: self.client_id, |
| 188 | command: Some(WriteOperation::Insert { |
| 189 | key: Bytes::copy_from_slice(key.as_ref()), |
| 190 | value: Bytes::copy_from_slice(value.as_ref()), |
| 191 | ttl_secs: None, |
| 192 | }), |
| 193 | }; |
| 194 | |
| 195 | let (resp_tx, resp_rx) = MaybeCloneOneshot::new(); |
| 196 | |
| 197 | self.cmd_tx |
| 198 | .send(d_engine_core::ClientCmd::Propose(request, resp_tx)) |
| 199 | .await |
| 200 | .map_err(|_| channel_closed_error())?; |
| 201 | |
| 202 | let result = tokio::time::timeout(self.timeout, resp_rx) |
| 203 | .await |
| 204 | .map_err(|_| timeout_error(self.timeout))? |
| 205 | .map_err(|_| channel_closed_error())?; |
| 206 | |
| 207 | let response = |
| 208 | result.map_err(|status| server_error(format!("RPC error: {}", status.message())))?; |
| 209 | |
| 210 | if response.error != ErrorCode::Success { |
| 211 | return Err(Self::map_error_response( |
| 212 | response.error, |
| 213 | response.leader_hint, |
| 214 | response.retry_after_ms, |
| 215 | )); |
| 216 | } |
| 217 | |
| 218 | Ok(()) |
| 219 | } |
| 220 | |
| 221 | /// Strongly consistent read (linearizable). |
| 222 | /// |