Skip to content

Commit

Permalink
rust: add demo Tonic server (#4318)
Browse files Browse the repository at this point in the history
Summary:
This patch defines a simple “demo” service with one RPC, which adds a
sequence of numbers. It includes a Tonic server for this service to
demonstrate the end-to-end setup.

Test Plan:
In one shell, run `bazel run -c opt //tensorboard/data/server`. In
another shell, use `grpc_cli` to send an RPC to localhost port 6789:

```
grpc_cli --channel_creds_type=insecure \
    --protofiles tensorboard/data/server/demo.proto \
    call localhost:6789 Demo.Add "term: 2 term: 2"
```

This should print a response like `sum: 4`. On my machine, it completes
in 5.2 ± 2.6 ms (methodology: run `hyperfine` on the above command).
This seems reasonably fast given that it has to establish a connection,
whereas a Python gRPC client will keep a connection open. It’s also well
below the 40ms magic number for `TCP_NODELAY` issues.

wchargin-branch: rust-demo-tonic-server
  • Loading branch information
wchargin authored Nov 12, 2020
1 parent 1fbc436 commit da59d4c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 3 deletions.
11 changes: 10 additions & 1 deletion tensorboard/data/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ licenses(["notice"])

# Protocol buffer packages (as in `package foo.bar;` directives) that we need
# to compile to Rust bindings.
_proto_packages = ["tensorboard"]
_proto_packages = [
"demo",
"tensorboard",
]

# Generated files with Rust protobuf bindings. These only exist in the build
# graph, not in the source tree. The file name pattern is specified by Prost
Expand Down Expand Up @@ -69,11 +72,17 @@ rust_binary(
name = "server",
srcs = ["main.rs"],
edition = "2018",
deps = [
":rustboard_core",
"//third_party/rust:tokio",
"//third_party/rust:tonic",
],
)

genrule(
name = "gen_protos",
srcs = [
":demo.proto",
"//tensorboard/compat/proto:proto_srcs",
],
outs = _genproto_files,
Expand Down
26 changes: 26 additions & 0 deletions tensorboard/data/server/demo.pb.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions tensorboard/data/server/demo.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
syntax = "proto3";

package demo;

service Demo {
rpc Add(AddRequest) returns (AddResponse);
}

message AddRequest {
repeated int32 term = 1;
}

message AddResponse {
int32 sum = 1;
}
8 changes: 7 additions & 1 deletion tensorboard/data/server/gen_protos_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ fn main() -> std::io::Result<()> {
tonic_build::configure()
.out_dir(&out_dir)
.format(false) // don't run `rustfmt`; shouldn't be needed to build
.compile(&["tensorboard/compat/proto/event.proto"], &["."])
.compile(
&[
"tensorboard/compat/proto/event.proto",
"tensorboard/data/server/demo.proto",
],
&["."],
)
.expect("compile_protos");
Ok(())
}
4 changes: 4 additions & 0 deletions tensorboard/data/server/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ mod scripted_reader;
/// Protocol buffer bindings.
#[allow(clippy::all)]
pub mod proto {
/// Bindings for `package demo`, used for a demo Tonic server.
pub mod demo {
include!("demo.pb.rs");
}
/// Bindings for `package tensorboard`, containing standard TensorFlow protos.
pub mod tensorboard {
include!("tensorboard.pb.rs");
Expand Down
36 changes: 35 additions & 1 deletion tensorboard/data/server/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,38 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

fn main() {}
#![allow(clippy::needless_update)] // https://github.com/rust-lang/rust-clippy/issues/6323

use tonic::{transport::Server, Request, Response};

use rustboard_core::proto::demo as pb;

#[derive(Debug, Default)]
struct DemoHandler;

#[tonic::async_trait]
impl pb::demo_server::Demo for DemoHandler {
async fn add(
&self,
request: Request<pb::AddRequest>,
) -> Result<Response<pb::AddResponse>, tonic::Status> {
let request = request.into_inner();
let sum: i32 = request.term.into_iter().sum();
let response = pb::AddResponse {
sum,
..Default::default()
};
Ok(Response::new(response))
}
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::0]:6789".parse::<std::net::SocketAddr>()?;
let handler = DemoHandler::default();
Server::builder()
.add_service(pb::demo_server::DemoServer::new(handler))
.serve(addr)
.await?;
Ok(())
}

0 comments on commit da59d4c

Please sign in to comment.