Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] Request validation #398

Closed
bsbds opened this issue Jul 26, 2023 · 0 comments · Fixed by #394
Closed

[Refactor] Request validation #398

bsbds opened this issue Jul 26, 2023 · 0 comments · Fixed by #394
Milestone

Comments

@bsbds
Copy link
Collaborator

bsbds commented Jul 26, 2023

Background

In the current etcd compatible design, when received request from client, the request is checked in the RPC server, then will it redirect the request to the curp server for processing. For example in kv_server.

    /// Range gets the keys in the range from the key-value store.
    #[instrument(skip_all)]
    async fn range(
        &self,
        request: tonic::Request<RangeRequest>,
    ) -> Result<tonic::Response<RangeResponse>, tonic::Status> {
        let range_req = request.get_ref();
        debug!("Receive grpc request: {:?}", range_req);
        Self::check_range_request(
            range_req,
            self.kv_storage.compacted_revision(),
            self.kv_storage.revision(),
        )?;

        ...
    }

However, as we introduce the outside client, which talk to the curp server directly. It is necessary to validate the requests in the storage backend.

Refactor

I plan to devide the validation check into two parts:

  1. The part that do not rely on the server state.
    eg. for a put request, the request must contain a key field, which can be checked statcially.

  2. The part that depends on the server state.
    eg. for a range request with a specific revision, we need to check whether the revision is larger than the latest revision on the server or less than the revision that are already compated.

For the first part I plan to introduce a RequestValidator trait containing a validation method, for each request that need to be validated, we can implement the trait for it. Then we can share this validation method in both the RPC server and the storage backend.

For the second part, as the checker need to return different error types for the client(on the contary the RPC server just return tonic Status). I plan to copy the original code to the storage backend and made some modifications to return these errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants