Skip to content

Commit

Permalink
create server
Browse files Browse the repository at this point in the history
  • Loading branch information
cospectrum committed Jan 3, 2024
1 parent 3b9e254 commit c023251
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 164 deletions.
19 changes: 19 additions & 0 deletions examples/protogen/Makefile.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[tasks.clean-server]
command = "rm"
args = ["-rf", "server"]

[tasks.clean-client]
command = "rm"
args = ["-rf", "client"]


[tasks.clean]
dependencies = [
"clean-server",
"clean-client",
]

[tasks.all]
command = "cargo"
args = ["run"]
dependencies = ["clean"]
6 changes: 5 additions & 1 deletion examples/protogen/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# protogen

```sh
cargo run proto/<name>.proto
cargo run
```
or
```sh
cargo make all
```
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
syntax = "proto3";
package cache_grpc;

package rpc;

service Getter {
service CacheRPC {
rpc Get(GetRequest) returns (GetResponse);
}

service Setter {
rpc Set(SetRequest) returns (SetResponse);
}

Expand All @@ -24,5 +20,4 @@ message SetRequest {
}

message SetResponse {
bool success = 1;
}
2 changes: 1 addition & 1 deletion examples/protogen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{fs, path::Path};

fn main() {
let args: Vec<String> = std::env::args().collect();
let default = "proto/grpc.proto".to_string();
let default = "proto/cache_grpc.proto".to_string();
let relative_path = args.get(1).unwrap_or(&default);

let curr_dir = std::env::current_dir().unwrap();
Expand Down
3 changes: 3 additions & 0 deletions memcrab-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ edition = "2021"
memcrab-cache = { version = "0.1.0", path = "../memcrab-cache" }
prost = { workspace = true }
tonic = { workspace = true }

[dev-dependencies]
tokio = { version = "1.35.1", features = ["full"] }
18 changes: 18 additions & 0 deletions memcrab-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# memcrab-server

```rust
use core::num::NonZeroUsize;
use memcrab_server::start_grpc_server;
use memcrab_cache::Cache;

#[tokio::main]
async fn main() {
let addr = "[::1]:50051".parse().unwrap();

let maxbytes = 100_000;
let maxlen = NonZeroUsize::new(110).unwrap();
let cache = Cache::new(maxlen, maxbytes);

start_grpc_server(addr, cache).await.unwrap();
}
```
16 changes: 16 additions & 0 deletions memcrab-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,19 @@
mod pb;

mod service;

use pb::cache_rpc_server::CacheRpcServer;
use service::Service;
use std::net::SocketAddr;
use tonic::transport::Server;

pub async fn start_grpc_server(
addr: SocketAddr,
cache: memcrab_cache::Cache,
) -> Result<(), tonic::transport::Error> {
let cache_srvice = Service::new(cache);
Server::builder()
.add_service(CacheRpcServer::new(cache_srvice))
.serve(addr)
.await
}
179 changes: 24 additions & 155 deletions memcrab-server/src/pb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,33 @@ pub struct SetRequest {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetResponse {
#[prost(bool, tag = "1")]
pub success: bool,
}
pub struct SetResponse {}
/// Generated server implementations.
pub mod getter_server {
pub mod cache_rpc_server {
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
use tonic::codegen::*;
/// Generated trait containing gRPC methods that should be implemented for use with GetterServer.
/// Generated trait containing gRPC methods that should be implemented for use with CacheRpcServer.
#[async_trait]
pub trait Getter: Send + Sync + 'static {
pub trait CacheRpc: Send + Sync + 'static {
async fn get(
&self,
request: tonic::Request<super::GetRequest>,
) -> std::result::Result<tonic::Response<super::GetResponse>, tonic::Status>;
async fn set(
&self,
request: tonic::Request<super::SetRequest>,
) -> std::result::Result<tonic::Response<super::SetResponse>, tonic::Status>;
}
#[derive(Debug)]
pub struct GetterServer<T: Getter> {
pub struct CacheRpcServer<T: CacheRpc> {
inner: _Inner<T>,
accept_compression_encodings: EnabledCompressionEncodings,
send_compression_encodings: EnabledCompressionEncodings,
max_decoding_message_size: Option<usize>,
max_encoding_message_size: Option<usize>,
}
struct _Inner<T>(Arc<T>);
impl<T: Getter> GetterServer<T> {
impl<T: CacheRpc> CacheRpcServer<T> {
pub fn new(inner: T) -> Self {
Self::from_arc(Arc::new(inner))
}
Expand Down Expand Up @@ -97,9 +98,9 @@ pub mod getter_server {
self
}
}
impl<T, B> tonic::codegen::Service<http::Request<B>> for GetterServer<T>
impl<T, B> tonic::codegen::Service<http::Request<B>> for CacheRpcServer<T>
where
T: Getter,
T: CacheRpc,
B: Body + Send + 'static,
B::Error: Into<StdError> + Send + 'static,
{
Expand All @@ -115,10 +116,10 @@ pub mod getter_server {
fn call(&mut self, req: http::Request<B>) -> Self::Future {
let inner = self.inner.clone();
match req.uri().path() {
"/rpc.Getter/Get" => {
"/cache_grpc.CacheRPC/Get" => {
#[allow(non_camel_case_types)]
struct GetSvc<T: Getter>(pub Arc<T>);
impl<T: Getter> tonic::server::UnaryService<super::GetRequest>
struct GetSvc<T: CacheRpc>(pub Arc<T>);
impl<T: CacheRpc> tonic::server::UnaryService<super::GetRequest>
for GetSvc<T> {
type Response = super::GetResponse;
type Future = BoxFuture<
Expand All @@ -131,7 +132,7 @@ pub mod getter_server {
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as Getter>::get(&inner, request).await
<T as CacheRpc>::get(&inner, request).await
};
Box::pin(fut)
}
Expand Down Expand Up @@ -159,142 +160,10 @@ pub mod getter_server {
};
Box::pin(fut)
}
_ => {
Box::pin(async move {
Ok(
http::Response::builder()
.status(200)
.header("grpc-status", "12")
.header("content-type", "application/grpc")
.body(empty_body())
.unwrap(),
)
})
}
}
}
}
impl<T: Getter> Clone for GetterServer<T> {
fn clone(&self) -> Self {
let inner = self.inner.clone();
Self {
inner,
accept_compression_encodings: self.accept_compression_encodings,
send_compression_encodings: self.send_compression_encodings,
max_decoding_message_size: self.max_decoding_message_size,
max_encoding_message_size: self.max_encoding_message_size,
}
}
}
impl<T: Getter> Clone for _Inner<T> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl<T: Getter> tonic::server::NamedService for GetterServer<T> {
const NAME: &'static str = "rpc.Getter";
}
}
/// Generated server implementations.
pub mod setter_server {
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
use tonic::codegen::*;
/// Generated trait containing gRPC methods that should be implemented for use with SetterServer.
#[async_trait]
pub trait Setter: Send + Sync + 'static {
async fn set(
&self,
request: tonic::Request<super::SetRequest>,
) -> std::result::Result<tonic::Response<super::SetResponse>, tonic::Status>;
}
#[derive(Debug)]
pub struct SetterServer<T: Setter> {
inner: _Inner<T>,
accept_compression_encodings: EnabledCompressionEncodings,
send_compression_encodings: EnabledCompressionEncodings,
max_decoding_message_size: Option<usize>,
max_encoding_message_size: Option<usize>,
}
struct _Inner<T>(Arc<T>);
impl<T: Setter> SetterServer<T> {
pub fn new(inner: T) -> Self {
Self::from_arc(Arc::new(inner))
}
pub fn from_arc(inner: Arc<T>) -> Self {
let inner = _Inner(inner);
Self {
inner,
accept_compression_encodings: Default::default(),
send_compression_encodings: Default::default(),
max_decoding_message_size: None,
max_encoding_message_size: None,
}
}
pub fn with_interceptor<F>(
inner: T,
interceptor: F,
) -> InterceptedService<Self, F>
where
F: tonic::service::Interceptor,
{
InterceptedService::new(Self::new(inner), interceptor)
}
/// Enable decompressing requests with the given encoding.
#[must_use]
pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {
self.accept_compression_encodings.enable(encoding);
self
}
/// Compress responses with the given encoding, if the client supports it.
#[must_use]
pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {
self.send_compression_encodings.enable(encoding);
self
}
/// Limits the maximum size of a decoded message.
///
/// Default: `4MB`
#[must_use]
pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
self.max_decoding_message_size = Some(limit);
self
}
/// Limits the maximum size of an encoded message.
///
/// Default: `usize::MAX`
#[must_use]
pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
self.max_encoding_message_size = Some(limit);
self
}
}
impl<T, B> tonic::codegen::Service<http::Request<B>> for SetterServer<T>
where
T: Setter,
B: Body + Send + 'static,
B::Error: Into<StdError> + Send + 'static,
{
type Response = http::Response<tonic::body::BoxBody>;
type Error = std::convert::Infallible;
type Future = BoxFuture<Self::Response, Self::Error>;
fn poll_ready(
&mut self,
_cx: &mut Context<'_>,
) -> Poll<std::result::Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: http::Request<B>) -> Self::Future {
let inner = self.inner.clone();
match req.uri().path() {
"/rpc.Setter/Set" => {
"/cache_grpc.CacheRPC/Set" => {
#[allow(non_camel_case_types)]
struct SetSvc<T: Setter>(pub Arc<T>);
impl<T: Setter> tonic::server::UnaryService<super::SetRequest>
struct SetSvc<T: CacheRpc>(pub Arc<T>);
impl<T: CacheRpc> tonic::server::UnaryService<super::SetRequest>
for SetSvc<T> {
type Response = super::SetResponse;
type Future = BoxFuture<
Expand All @@ -307,7 +176,7 @@ pub mod setter_server {
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as Setter>::set(&inner, request).await
<T as CacheRpc>::set(&inner, request).await
};
Box::pin(fut)
}
Expand Down Expand Up @@ -350,7 +219,7 @@ pub mod setter_server {
}
}
}
impl<T: Setter> Clone for SetterServer<T> {
impl<T: CacheRpc> Clone for CacheRpcServer<T> {
fn clone(&self) -> Self {
let inner = self.inner.clone();
Self {
Expand All @@ -362,7 +231,7 @@ pub mod setter_server {
}
}
}
impl<T: Setter> Clone for _Inner<T> {
impl<T: CacheRpc> Clone for _Inner<T> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
Expand All @@ -372,7 +241,7 @@ pub mod setter_server {
write!(f, "{:?}", self.0)
}
}
impl<T: Setter> tonic::server::NamedService for SetterServer<T> {
const NAME: &'static str = "rpc.Setter";
impl<T: CacheRpc> tonic::server::NamedService for CacheRpcServer<T> {
const NAME: &'static str = "cache_grpc.CacheRPC";
}
}
Loading

0 comments on commit c023251

Please sign in to comment.