暂无描述

Jing Yang 1589bfa521 Add license file, update toml, ready to publish. 5 年之前
src 97146550d1 Reset the connection only when all previous commands succeeded. 5 年之前
.gitignore bb2e035b8a Generated crate skeleton. 5 年之前
Cargo.toml 1589bfa521 Add license file, update toml, ready to publish. 5 年之前
MIT-LICENSE 1589bfa521 Add license file, update toml, ready to publish. 5 年之前
README.md 198dbbbef3 Add readme. 5 年之前
rustfmt.toml a2d6c7ef16 First draft, contains server and network. 5 年之前

README.md

An RPC framework for testing: labrpc

This is a line-by-line translation of labrpc from Go to Rust. labrpc helps test a distributed system in a controlled environment. It can simulate networks that has long delays, drops packets randomly, or sends RPC responses in random order. Peers connected to the network can be added and removed on the fly, or disabled and re-enabled individually.

This Rust version utilizes the async-await feature, making the implementation safe, reliable and efficient at the same time.

Usage

labrpc allows creating a network that passes RPC calls. RPCs servers can be registered in the network, with a unique name. Clients can connect to servers via server names. Each client is identified by its name, so that they can bedisabled if and when needed.

A typical use case is as follows.

    // Start the network.
    let network = labrpc::Network::run_daemon();
    // Make it unreliable.
    network.lock().set_reliable(true);

    // Make an RPC server.
    let server = { ... };
    // Register the server in the network, call it "echo-server".
    network.lock().add_server(&"echo-server", server);
    
    // Make a connection to the above server.
    let client = network.lock().make_client(&"echo-client", &"echo-server");
    // Build and send a request.
    let request = { ... };
    // Await for the reply.
    let reply = client.call_rpc("EchoService.Echo", request).await?;

    // Echo server should echo.
    assert_eq!(request.get_message(), reply.get_message());

    // Disable the client we created above.
    network.lock().set_enable_client(&"echo-client", false);

    // Now we should get errors.
    let result = client.call_rpc("EchoServer.Echo").await;
    assert!(resut.is_err());

Implementation

Behind the scenes, all clients send requests through a shared request queue. There is a dedicated thread taking requests from the queue and delegating the request to a set of workers. Each worker looks up the client, checks ACLs, finds the right server, and calls the server. Workers also decides if the request should be dropped or delayed.

Latency

On average, each RPC takes about 60ms to travel through the network.

For unknown reasons, this implementation is only half as fast as the Go version, in the scenario where there is only one client which sends millions of requests. Adding more clients that behaves similarly does not decrease performance.