-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(health): Add tonic-health server impl
This commit adds a new crate `tonic-health` which implements the [standard GRPC Health Checking][checking] protocol. Currently there is only a server implementation, though others have alluded in the discussion in #135 that client implementations exist which could also be imported as necessary. A example server has also been added - once the client work is done a client for this should be added also. [checking]: https://github.com/grpc/grpc/blob/master/doc/health-checking.md Fixes #135.
- Loading branch information
Showing
10 changed files
with
478 additions
and
0 deletions.
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
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
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,68 @@ | ||
use tonic::{transport::Server, Request, Response, Status}; | ||
|
||
use hello_world::greeter_server::{Greeter, GreeterServer}; | ||
use hello_world::{HelloReply, HelloRequest}; | ||
use std::time::Duration; | ||
use tokio::time::delay_for; | ||
use tonic_health::server::HealthReporter; | ||
|
||
pub mod hello_world { | ||
tonic::include_proto!("helloworld"); | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct MyGreeter {} | ||
|
||
#[tonic::async_trait] | ||
impl Greeter for MyGreeter { | ||
async fn say_hello( | ||
&self, | ||
request: Request<HelloRequest>, | ||
) -> Result<Response<HelloReply>, Status> { | ||
println!("Got a request from {:?}", request.remote_addr()); | ||
|
||
let reply = hello_world::HelloReply { | ||
message: format!("Hello {}!", request.into_inner().name), | ||
}; | ||
Ok(Response::new(reply)) | ||
} | ||
} | ||
|
||
/// This function (somewhat improbably) flips the status of a service every second, in order | ||
/// that the effect of `tonic_health::HealthReporter::watch` can be easily observed. | ||
async fn twiddle_service_status(mut reporter: HealthReporter) { | ||
let mut iter = 0u64; | ||
loop { | ||
iter += 1; | ||
delay_for(Duration::from_secs(1)).await; | ||
|
||
if iter % 2 == 0 { | ||
reporter.set_serving::<GreeterServer<MyGreeter>>().await; | ||
} else { | ||
reporter.set_not_serving::<GreeterServer<MyGreeter>>().await; | ||
}; | ||
} | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let (mut health_reporter, health_service) = tonic_health::server::health_reporter(); | ||
health_reporter | ||
.set_serving::<GreeterServer<MyGreeter>>() | ||
.await; | ||
|
||
tokio::spawn(twiddle_service_status(health_reporter.clone())); | ||
|
||
let addr = "[::1]:50051".parse().unwrap(); | ||
let greeter = MyGreeter::default(); | ||
|
||
println!("HealthServer + GreeterServer listening on {}", addr); | ||
|
||
Server::builder() | ||
.add_service(health_service) | ||
.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,30 @@ | ||
[package] | ||
name = "tonic-health" | ||
version = "0.1.0" | ||
authors = ["James Nugent <[email protected]>"] | ||
edition = "2018" | ||
license = "MIT" | ||
repository = "https://github.com/hyperium/tonic" | ||
homepage = "https://github.com/hyperium/tonic" | ||
description = """ | ||
Health Checking module of `tonic` gRPC implementation. | ||
""" | ||
readme = "README.md" | ||
categories = ["network-programming", "asynchronous"] | ||
keywords = ["rpc", "grpc", "async", "healthcheck"] | ||
|
||
[features] | ||
transport = ["tonic/transport"] | ||
|
||
[dependencies] | ||
async-stream = "0.2" | ||
tokio = { version = "0.2", features = ["sync", "stream"] } | ||
tonic = { path = "../tonic", features = ["codegen", "data-prost"] } | ||
bytes = "0.5" | ||
prost = "0.6" | ||
|
||
[dev-dependencies] | ||
tokio = { version = "0.2", features = ["rt-core", "macros"]} | ||
|
||
[build-dependencies] | ||
tonic-build = { path = "../tonic-build" } |
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,9 @@ | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
tonic_build::configure() | ||
.build_server(true) | ||
.build_client(false) | ||
.format(true) | ||
.compile(&["proto/health.proto"], &["proto/"])?; | ||
|
||
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,22 @@ | ||
syntax = "proto3"; | ||
|
||
package grpc.health.v1; | ||
|
||
message HealthCheckRequest { | ||
string service = 1; | ||
} | ||
|
||
message HealthCheckResponse { | ||
enum ServingStatus { | ||
UNKNOWN = 0; | ||
SERVING = 1; | ||
NOT_SERVING = 2; | ||
} | ||
ServingStatus status = 1; | ||
} | ||
|
||
service Health { | ||
rpc Check(HealthCheckRequest) returns (HealthCheckResponse); | ||
|
||
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); | ||
} |
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,35 @@ | ||
use std::fmt::{Display, Formatter}; | ||
|
||
mod proto { | ||
tonic::include_proto!("grpc.health.v1"); | ||
} | ||
|
||
pub mod server; | ||
|
||
/// An enumeration of values representing gRPC service health. | ||
#[derive(Copy, Clone, Debug, PartialEq)] | ||
pub enum ServingStatus { | ||
Unknown, | ||
Serving, | ||
NotServing, | ||
} | ||
|
||
impl Display for ServingStatus { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
ServingStatus::Unknown => f.write_str("Unknown"), | ||
ServingStatus::Serving => f.write_str("Serving"), | ||
ServingStatus::NotServing => f.write_str("NotServing"), | ||
} | ||
} | ||
} | ||
|
||
impl From<ServingStatus> for proto::health_check_response::ServingStatus { | ||
fn from(s: ServingStatus) -> Self { | ||
match s { | ||
ServingStatus::Unknown => proto::health_check_response::ServingStatus::Unknown, | ||
ServingStatus::Serving => proto::health_check_response::ServingStatus::Serving, | ||
ServingStatus::NotServing => proto::health_check_response::ServingStatus::NotServing, | ||
} | ||
} | ||
} |
Oops, something went wrong.