pub async fn query(
        &self,
        qr: command::QueryRequest,
        redirect: bool,
    ) -> StoreResult<command::QueryResult> {
        let level = command::query_request::Level::from_i32(qr.level)
            .ok_or(APIError::Query(format!("invalid query level {}", qr.level)))?;
        match level {
            command::query_request::Level::QueryRequestLevelStrong => {
                // check leader
                let resp = self.redirect_if_needed(&qr, redirect).await?;
                if let Some(forward_resp) = resp {
                    match forward_resp {
                        ForwardResponse::AppResponse(app_resp) => match app_resp {
                            AppResponse::Query(qs) => return Ok(qs),
                            _ => panic!("BUG: need QueryResult"),
                        },
                        _ => panic!("BUG: need AppRsponse"),
                    }
                }

                let rpc = ClientWriteRequest::new(EntryPayload::Normal(AppRequest::Query(qr)));
                let resp = self
                    .raft
                    .client_write(rpc)
                    .await
                    .map_err(|e| APIError::Query(format!("{}", e)))?;
                match resp.data {
                    AppResponse::Query(res) => Ok(res),
                    _ => {
                        return Err(APIError::Query(format!(
                            "Need QueryResult, but got {}",
                            resp.data
                        ))
                        .into())
                    }
                }
            }
            command::query_request::Level::QueryRequestLevelWeak => {
                self.raft
                    .is_leader()
                    .await
                    .map_err(|e| APIError::NotLeader(format!("Not a leader {}", e)))?;
                // TODO after remove rwlock in FSM, here we need to acquire read lock when
                // req.transaction is true.
                let res = self.state_machine().query(&qr).await?;
                Ok(res)
            }
            command::query_request::Level::QueryRequestLevelNone => {
                let elapsed = self.last_contact_time.read().await.elapsed();
                // .map_err(|e| APIError::Query(format!("{}", e)))?

                if qr.freshness > 0 && elapsed.as_nanos() > (qr.freshness as u128) {
                    return Err(APIError::StaleRead(String::from("stale read")).into());
                }

                // TODO after remove rwlock in FSM, here we need to acquire read lock when
                // req.transaction is true.
                let res = self.state_machine().query(&qr).await?;
                Ok(res)
            }
        }
    }
// Query the database, the meaning of level:
// Strong: auto forward the request to leader if current node is follower, and
// the leader will use RAFT alog to query the database. Weak: auto forward
// request to leader if current node is follower and the leader will
// query the local SQLite directly. None: just query the local SQLite directly.
Query the database, the meaning of level:
Strong: auto forward the request to leader if current node is follower, and
the leader will use RAFT alog to query the database. Weak: auto forward
request to leader if current node is follower and the leader will
query the local SQLite directly. None: just query the local SQLite directly.
Query the database the meaning of level : Strong : auto forward the request to leader if current node is follower and the leader will use RAFT alog to query the database . Weak : auto forward request to leader if current node is follower and the leader will query the local SQLite directly . None : just query the local SQLite directly .
pub async fn query(
        &self,
        qr: command::QueryRequest,
        redirect: bool,
    ) -> StoreResult<command::QueryResult> {
        let level = command::query_request::Level::from_i32(qr.level)
            .ok_or(APIError::Query(format!("invalid query level {}", qr.level)))?;
        match level {
            command::query_request::Level::QueryRequestLevelStrong => {
                // check leader
                let resp = self.redirect_if_needed(&qr, redirect).await?;
                if let Some(forward_resp) = resp {
                    match forward_resp {
                        ForwardResponse::AppResponse(app_resp) => match app_resp {
                            AppResponse::Query(qs) => return Ok(qs),
                            _ => panic!("BUG: need QueryResult"),
                        },
                        _ => panic!("BUG: need AppRsponse"),
                    }
                }
                let rpc = ClientWriteRequest::new(EntryPayload::Normal(AppRequest::Query(qr)));
                let resp = self
                    .raft
                    .client_write(rpc)
                    .await
                    .map_err(|e| APIError::Query(format!("{}", e)))?;
                match resp.data {
                    AppResponse::Query(res) => Ok(res),
                    _ => {
                        return Err(APIError::Query(format!(
                            "Need QueryResult, but got {}",
                            resp.data
                        ))
                        .into())
                    }
                }
            }
            command::query_request::Level::QueryRequestLevelWeak => {
                self.raft
                    .is_leader()
                    .await
                    .map_err(|e| APIError::NotLeader(format!("Not a leader {}", e)))?;
                // TODO after remove rwlock in FSM, here we need to acquire read lock when
                // req.transaction is true.
                let res = self.state_machine().query(&qr).await?;
                Ok(res)
            }
            command::query_request::Level::QueryRequestLevelNone => {
                let elapsed = self.last_contact_time.read().await.elapsed();
                // .map_err(|e| APIError::Query(format!("{}", e)))?
                if qr.freshness > 0 && elapsed.as_nanos() > (qr.freshness as u128) {
                    return Err(APIError::StaleRead(String::from("stale read")).into());
                }
                // TODO after remove rwlock in FSM, here we need to acquire read lock when
                // req.transaction is true.
                let res = self.state_machine().query(&qr).await?;
                Ok(res)
            }
        }
    }
pub async fn query ( & self , qr : command :: QueryRequest , redirect : bool , ) -> StoreResult < command :: QueryResult > { let level = command :: query_request :: Level :: from_i32 ( qr . level ) . ok_or ( APIError :: Query ( format ! ( " " qr level ) ) ) ? ; match level { command :: query_request :: Level :: QueryRequestLevelStrong => { // check leader let resp = self . redirect_if_needed ( & qr , redirect ) . await ? ; if let Some ( forward_resp ) = resp { match forward_resp { ForwardResponse :: AppResponse ( app_resp ) => match app_resp { AppResponse :: Query ( qs ) => return Ok ( qs ) , _ => panic ! ( " " ) , } , _ => panic ! ( " " ) , } } let rpc = ClientWriteRequest :: new ( EntryPayload :: Normal ( AppRequest :: Query ( qr ) ) ) ; let resp = self . raft . client_write ( rpc ) . await . map_err ( | e | APIError :: Query ( format ! ( " " e ) ) ) ? ; match resp . data { AppResponse :: Query ( res ) => Ok ( res ) , _ => { return Err ( APIError :: Query ( format ! ( " " resp data ) ) . into ( ) ) } } } command :: query_request :: Level :: QueryRequestLevelWeak => { self . raft . is_leader ( ) . await . map_err ( | e | APIError :: NotLeader ( format ! ( " " e ) ) ) ? ; // TODO after remove rwlock in FSM, here we need to acquire read lock when // req.transaction is true. let res = self . state_machine ( ) . query ( & qr ) . await ? ; Ok ( res ) } command :: query_request :: Level :: QueryRequestLevelNone => { let elapsed = self . last_contact_time . read ( ) . await . elapsed ( ) ; // .map_err(|e| APIError::Query(format!("{}", e)))? if qr . freshness > 0 && elapsed . as_nanos ( ) > ( qr . freshness as u128 ) { return Err ( APIError :: StaleRead ( String :: from ( " " ) ) . into ( ) ) ; } // TODO after remove rwlock in FSM, here we need to acquire read lock when // req.transaction is true. let res = self . state_machine ( ) . query ( & qr ) . await ? ; Ok ( res ) } } }
Query the database, the meaning of level:
Strong: auto forward the request to leader if current node is follower, and
the leader will use RAFT alog to query the database.
Query the database the meaning of level : Strong : auto forward the request to leader if current node is follower and the leader will use RAFT alog to query the database .
&self
qr
command::QueryRequest
redirect
bool
&self
qr
command::QueryRequest
redirect
bool