-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add flatbuffer tonic demo #3
Merged
Merged
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
a0d2b34
modify docs
zealchen f1331f5
add unsafe feature within flatbuffer
zealchen 713df5b
add docs
zealchen 0bfe53b
fix cr
zealchen 7b4549e
add fatbuffer tonic demo
zealchen 08fd173
add flatbuffer gRPC demo
zealchen edd1846
cf fix
zealchen 464054c
merge master
zealchen de6fd78
add file
zealchen 02cfddf
cf fix
zealchen f4ade2c
add
zealchen c7ec76a
add flac deps
zealchen f4d56a0
add
zealchen 10e31c1
skip fb rs check
zealchen b55bfa4
add flatc deps
zealchen 2ccb6b2
modify
zealchen d9ba06e
modify
zealchen 3fa5d22
add
zealchen 4cc63da
add
zealchen 5708ecd
add
zealchen 60d2c8a
Update fb_tonic_demo/src/util/common.rs
jiacai2050 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,28 @@ | ||
[package] | ||
[workspace.package] | ||
name = "serialization-benchmark-rs" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[workspace] | ||
resolver = "2" | ||
# In alphabetical order | ||
members = [ | ||
"fb_tonic_demo", | ||
] | ||
|
||
[dependencies] | ||
[workspace.dependencies] | ||
bytes = "1.6.0" | ||
clap = { version = "4.5.4", features = ["derive", "env"] } | ||
flatbuffers = "24.3.25" | ||
fury = { git= "https://github.com/apache/incubator-fury.git", branch = "main" } | ||
lazy_static = "1.4.0" | ||
prettytable-rs = "0.10.0" | ||
prost = "0.12.4" | ||
sysinfo = "0.30.11" | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0.116" | ||
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] } | ||
tonic = "0.11.0" | ||
|
||
[build-dependencies] | ||
[workspace.build-dependencies] | ||
tonic-build = "0.11.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "fb_tonic_demo" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
bytes = { workspace = true } | ||
flatbuffers = { workspace = true } | ||
prost = { workspace = true } | ||
serde = { workspace = true } | ||
serde_json = { workspace = true } | ||
tokio = { workspace = true } | ||
tonic = { workspace = true } | ||
|
||
[build-dependencies] | ||
tonic-build = "0.11.0" | ||
|
||
[[bin]] | ||
name = "server" | ||
path = "src/server.rs" | ||
|
||
[[bin]] | ||
name = "client" | ||
path = "src/client.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# How to run flatbuffer tonic demo? | ||
|
||
```sh | ||
cargo run --bin server | ||
cargo run --bin client | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use std::io::Result; | ||
|
||
fn main() -> Result<()> { | ||
let greeter_service = tonic_build::manual::Service::builder() | ||
.name("Greeter") | ||
.package("fb.helloworld") | ||
.method( | ||
tonic_build::manual::Method::builder() | ||
.name("say_hello") | ||
.route_name("SayHello") | ||
.input_type("crate::util::common::FlatBufferBytes") | ||
.output_type("crate::util::common::FlatBufferBytes") | ||
.codec_path("crate::util::common::FlatBufferCodec") | ||
.build(), | ||
) | ||
.build(); | ||
|
||
tonic_build::manual::Builder::new() | ||
.out_dir("src/util") | ||
.compile(&[greeter_service]); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#![allow(unused)] | ||
pub mod util; | ||
use util::common::FlatBufferBytes; | ||
use util::fbgreeting_generated::fbdemo::Greetings; | ||
use util::fbgreeting_generated::fbdemo::GreetingsArgs; | ||
|
||
pub mod hello_world { | ||
include!("util/fb.helloworld.Greeter.rs"); | ||
} | ||
use hello_world::greeter_client::GreeterClient; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let mut client = GreeterClient::connect("http://[::1]:50051").await?; | ||
|
||
let mut builder: flatbuffers::FlatBufferBuilder<'_> = | ||
flatbuffers::FlatBufferBuilder::with_capacity(1024); | ||
|
||
let name = builder.create_string("Alice"); | ||
let words = builder.create_string("Hello~~"); | ||
|
||
let root_offset: flatbuffers::WIPOffset<Greetings<'_>> = Greetings::create( | ||
&mut builder, | ||
&GreetingsArgs { | ||
name: Some(name), | ||
words: Some(words), | ||
}, | ||
); | ||
let request = tonic::Request::new(FlatBufferBytes::serialize(builder, root_offset)); | ||
let response = client.say_hello(request).await?; | ||
|
||
let r = response.into_inner(); | ||
if let Ok(greetings) = r.deserialize::<Greetings>() { | ||
println!( | ||
"Greetings from {:?}: {:?}", | ||
greetings.name().unwrap(), | ||
greetings.words().unwrap() | ||
); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#![allow(unused)] | ||
use tonic::{transport::Server, Request, Response, Status}; | ||
|
||
pub mod util; | ||
use util::common::FlatBufferBytes; | ||
use util::fbgreeting_generated::fbdemo::Greetings; | ||
use util::fbgreeting_generated::fbdemo::GreetingsArgs; | ||
|
||
pub mod hello_world { | ||
include!("util/fb.helloworld.Greeter.rs"); | ||
} | ||
use hello_world::greeter_server::{Greeter, GreeterServer}; | ||
|
||
#[derive(Default)] | ||
pub struct MyGreeter {} | ||
|
||
#[tonic::async_trait] | ||
impl Greeter for MyGreeter { | ||
async fn say_hello( | ||
&self, | ||
request: Request<FlatBufferBytes>, | ||
) -> Result<Response<FlatBufferBytes>, Status> { | ||
let req = request.into_inner(); | ||
if let Ok(greetings) = req.deserialize::<Greetings>() { | ||
println!( | ||
"Greetings from {:?}: {:?}", | ||
greetings.name().unwrap(), | ||
greetings.words().unwrap() | ||
); | ||
} | ||
|
||
let mut builder = flatbuffers::FlatBufferBuilder::with_capacity(1024); | ||
let name = builder.create_string("bob"); | ||
let words = builder.create_string("world~~"); | ||
|
||
let root_offset: flatbuffers::WIPOffset<Greetings<'_>> = Greetings::create( | ||
&mut builder, | ||
&GreetingsArgs { | ||
name: Some(name), | ||
words: Some(words), | ||
}, | ||
); | ||
let resp = FlatBufferBytes::serialize(builder, root_offset); | ||
Ok(Response::new(resp)) | ||
} | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let addr = "[::1]:50051".parse().unwrap(); | ||
let greeter = MyGreeter::default(); | ||
|
||
println!("GreeterServer listening on {}", addr); | ||
|
||
Server::builder() | ||
.add_service(GreeterServer::new(greeter)) | ||
.serve(addr) | ||
.await?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//! This module defines common request/response types as well as the JsonCodec that is used by the | ||
//! json.helloworld.Greeter service which is defined manually (instead of via proto files) by the | ||
//! `build_json_codec_service` function in the `examples/build.rs` file. | ||
extern crate flatbuffers; | ||
use bytes::{Buf, BufMut}; | ||
use std::io::Read; | ||
use tonic::{ | ||
codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder}, | ||
Status, | ||
}; | ||
|
||
// TODO: Any better solutions to manage the flatbuffer objects? | ||
// As the associated type Encode / Decode of Trait Codec has a 'static lifetime bound which means | ||
// items been encoded or decoded shall not have any non static references. | ||
// However flatbuffer related types always have a 'fbb lifetime bound, I found no way to implement | ||
// something like serde do. | ||
jiacai2050 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub struct FlatBufferBytes { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里没必要单独定义这么一个结构吧?直接用 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sense. Done. |
||
data: Vec<u8>, | ||
head: usize, | ||
} | ||
|
||
impl FlatBufferBytes { | ||
pub fn new(data: Vec<u8>, head: usize) -> Self { | ||
Self { data, head } | ||
} | ||
|
||
pub fn valid_slice(&self) -> &[u8] { | ||
&(self.data[self.head..]) | ||
} | ||
|
||
pub fn serialize<'buf, T: flatbuffers::Follow<'buf> + 'buf>( | ||
mut builder: flatbuffers::FlatBufferBuilder<'buf>, | ||
root_offset: flatbuffers::WIPOffset<T>, | ||
) -> Self { | ||
builder.finish(root_offset, None); | ||
let (data, head) = builder.collapse(); | ||
Self { data, head } | ||
} | ||
|
||
pub fn deserialize<'buf, T: flatbuffers::Follow<'buf> + flatbuffers::Verifiable + 'buf>( | ||
&'buf self, | ||
) -> Result<T::Inner, Box<dyn std::error::Error>> { | ||
let data = self.valid_slice(); | ||
flatbuffers::root::<T>(data).map_err(|x| Box::new(x) as Box<dyn std::error::Error>) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct FlatBufferEncoder(); | ||
|
||
impl Encoder for FlatBufferEncoder { | ||
type Item = FlatBufferBytes; | ||
type Error = Status; | ||
|
||
fn encode(&mut self, item: Self::Item, buf: &mut EncodeBuf<'_>) -> Result<(), Self::Error> { | ||
buf.put_slice(item.valid_slice()); | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct FlatBufferDecoder(); | ||
|
||
impl Decoder for FlatBufferDecoder { | ||
type Item = FlatBufferBytes; | ||
type Error = Status; | ||
|
||
fn decode(&mut self, buf: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> { | ||
if !buf.has_remaining() { | ||
return Ok(None); | ||
} | ||
let mut data: Vec<u8> = Vec::new(); | ||
buf.reader() | ||
.read_to_end(&mut data) | ||
.map_err(|e| Status::internal(e.to_string()))?; | ||
let item = FlatBufferBytes::new(data, 0); | ||
Ok(Some(item)) | ||
} | ||
} | ||
|
||
/// A [`Codec`] that implements `application/grpc+json` via the serde library. | ||
#[derive(Debug, Clone, Default)] | ||
pub struct FlatBufferCodec(); | ||
|
||
impl Codec for FlatBufferCodec { | ||
type Encode = FlatBufferBytes; | ||
type Decode = FlatBufferBytes; | ||
type Encoder = FlatBufferEncoder; | ||
type Decoder = FlatBufferDecoder; | ||
|
||
fn encoder(&mut self) -> Self::Encoder { | ||
FlatBufferEncoder() | ||
} | ||
|
||
fn decoder(&mut self) -> Self::Decoder { | ||
FlatBufferDecoder() | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这种构建生成的一般不放到 git 里面,一般都是 target 里面,我们之前生成 fb 代码是这么写的:
然后在 lib.rs 里这样写
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
或者 OUT_DIR 这个环境变量
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best Practice. Done!