brpc-rs: Apache BRPC library for Rust

Build Status Crate Documentation

Apache BRPC is an industrial-grade RPC framework for building reliable and high-performance services. brpc-rs enables BRPC clients and servers implemented in the Rust programming language.

Status

This project is currently a prototype under active development. Many APIs are missing; the provided APIs are not guaranteed to be stable until 1.0.

Repository structure

This graph illustrates how the crates work together:

Quickstart

Prerequisites

First build and install Apache BRPC. Instructions can be found in getting_started.md.

Alternatively, you may use the prebuilt deb packages of Apache BRPC 0.9.6 for Ubuntu 16.04/18.04. These are NOT official packages.

Make sure these dependencies are already installed:

$ sudo apt-get install libprotobuf-dev libprotoc-dev protobuf-compiler $ sudo apt-get install libssl-dev libgflags-dev libleveldb-dev

Install brpc-protoc-plugin from crates.io.

shell $ cargo install brpc-protoc-plugin --version 0.1.0-alpha4

Now we are ready to start a brpc-rs project.

Cargo.toml

Let's create a small crate, echo_service, that includes an echo_client and an echo_server.

shell $ cargo new echo_service && cd echo_service

In Cargo.toml , add brpc-rs, prost and bytes to the [dependencies] section; add brpc-build to the [build-dependencies] section. For example,

```toml [build-dependencies] brpc-build = "0.1.0"

[dependencies] brpc-rs = "0.1.0" prost = "0.5.0" bytes = "0.4.12" ```

Define two binaries: echo_client and echo_server in Cargo.toml

```toml [[bin]] name = "echo_client" path = "src/client.rs"

[[bin]] name = "echo_server" path = "src/server.rs" ```

build.rs

Put a protobuf file echo.proto in src. This file defines EchoRequest, EchoResponse and EchoService.

protobuf syntax="proto2"; package example; message EchoRequest { required string message = 1; }; message EchoResponse { required string message = 1; }; service EchoService { rpc echo(EchoRequest) returns (EchoResponse); };

Add a line build = "build.rs" in the [package] section in Cargo.toml. Then, create a file called build.rs to generate bindings from src/echo.proto.

rust fn main() { brpc_build::compile_protos(&["src/echo.proto"], &["src"]).unwrap(); }

Note the package name in echo.proto is example. So build.rs would generate two files named example.rs and example.brpc.rs.

src/server.rs

Next let's implement the echo server. Create src/server.rs as follows:

```rust use brpc_rs::{Server, ServerOptions, ServiceOwnership};

pub mod echo { include!(concat!(env!("OUTDIR"), "/example.rs")); include!(concat!(env!("OUTDIR"), "/example.brpc.rs")); }

fn main() { let mut service = echo::EchoService::new(); service.setechohandler(&mut move |request, mut response| { response.message = request.message.clone(); Ok(()) });

let mut server = Server::new();
let mut options = ServerOptions::new();
options.set_idle_timeout_ms(1000);
server
    .add_service(&service, ServiceOwnership::ServerDoesntOwnService)
    .expect("Failed to add service");
server.start(50000, &options).expect("Failed to start service");
server.run(); // Run until CTRL-C

} ```

Because EchoService defines a function called echo() in echo.proto, the brpc-protoc-plugin generates the Rust definition of set_echo_handler() for EchoService. set_echo_handler() accepts a closure which handles EchoRequest sent from clients and returns an EchoResponse with the same message. The remaining lines create a server that listens at 0.0.0.0:50000.

src/client.rs

```rust use brpc_rs::{Channel, ChannelOptions};

pub mod echo { include!(concat!(env!("OUTDIR"), "/example.rs")); include!(concat!(env!("OUTDIR"), "/example.brpc.rs")); }

fn main() { let mut options = ChannelOptions::new(); options.settimeoutms(100); let addr = "127.0.0.1:50000".parse().expect("Invalid socket address"); let ch = Channel::withoptions(&addr, &options); let client = echo::EchoServiceStub::withchannel(&ch); let request = echo::EchoRequest { message: "hello".to_owned(), }; match client.echo(&request) { Ok(r) => println!("Response: {:?}", r), Err(e) => eprintln!("Error: {:?}", e), } } ```

The client first creates a Channel and initializes a service_stub with that channel. The client then calls service_stub.echo() to send a request..

Running the client and server

shell $ cargo run --bin echo_server & $ cargo run --bin echo_client Response: EchoResponse { message: "hello" }

Maintainer

License

brpc-rs is provided under Apache License, Version 2.0. For a copy, see the LICENSE file.