Rust知名库hyper源码分析(一)

您所在的位置:网站首页 表白代码库 Rust知名库hyper源码分析(一)

Rust知名库hyper源码分析(一)

2023-04-06 08:53| 来源: 网络整理| 查看: 265

对Rust的吐槽

Rust不得不说挺牛的,能够尽可能的解决内存不安全的问题。但是方式确实太诡异了,没见过哪个语言这么强调生命周期。类型系统也听牛的,学完都不知道在讲什么。哎,也许是自己太笨了。

关于Hyper库

hyper这个库偏底层,不会有多少人拿这个去开发业务的。但是reqwest库和warp库是基于它开发的,默认的异步运行时是tokio,算是一个比较好的研究对象。

先看以下官方的建立一个Server的代码:

use hyper::{Body, Method, Request, Response, Server, StatusCode}; use hyper::service::{make_service_fn, service_fn}; async fn echo(req: Request) -> Result { match (req.method(), req.uri().path()) { (&Method::GET, "/") => Ok(Response::new(Body::from( "Try POSTing data to /echo such as: `curl localhost:3000/echo -XPOST -d 'hello world'`" ))), (&Method::POST, "/echo") => Ok(Response::new(req.into_body())), // (&Method::POST, "/echo/uppercase") => { // let chunk_stream = req.into_body().map_ok(|chunk| { // chunk // .iter() // .map(|byte| byte.to_ascii_uppercase()) // .collect::() // }); // } (&Method::POST, "/echo/reversed") => { let whole_body = hyper::body::to_bytes(req.into_body()).await?; let reversed_body = whole_body.iter().rev().cloned().collect::(); Ok(Response::new(Body::from(reversed_body))) } _ => { let mut not_fund = Response::default(); *not_fund.status_mut() = StatusCode::NOT_FOUND; Ok(not_fund) } } } #[tokio::main] async fn main() -> Result { let addr = ([127, 0, 0, 1], 3000).into(); let service = make_service_fn(|_| async { Ok::(service_fn(echo)) }); let server = Server::bind(&addr) .serve(service); println!("Listening on http://{}", addr); server.await?; Ok(()) }

let addr = ([127, 0, 0, 1], 3000).into(); //主要是通过convert的Into trait调用From trait的实现

let service = make_service_fn(|_| async { Ok::(service_fn(echo)) });

这里主要分析service_fn()函数和make_service_fn函数

service_fn()函数在service/util.rs文件中

pub fn service_fn(f: F) -> ServiceFn where F: FnMut(Request) -> S, S: Future, { ServiceFn { f, _req: PhantomData, } }

service_fn函数会返回一个ServiceFn(F, R)的结构体,而这接口体实现了两个Trait,一个是fmt::Debug Trait,一个是tower库中的tower_service模块中的Service Trait。

着重分析tower的Service Trait。Service中仅有两个方法,poll_ready()与call()。具体实现要求参考tower注释。

make_service_fn()函数则返回MakeServiceFn结构体,同样,MakeServiceFn结构体也实现了fmt:Debug和tower_service模块的Service Trait.

pub trait Service { /// Responses given by the service. type Response; /// Errors produced by the service. type Error; /// The future response value. type Future: Future; /// Returns `Poll::Ready(Ok(()))` when the service is able to process requests. /// /// If the service is at capacity, then `Poll::Pending` is returned and the task /// is notified when the service becomes ready again. This function is /// expected to be called while on a task. Generally, this can be done with /// a simple `futures::future::poll_fn` call. /// /// If `Poll::Ready(Err(_))` is returned, the service is no longer able to service requests /// and the caller should discard the service instance. /// /// Once `poll_ready` returns `Poll::Ready(Ok(()))`, a request may be dispatched to the /// service using `call`. Until a request is dispatched, repeated calls to /// `poll_ready` must return either `Poll::Ready(Ok(()))` or `Poll::Ready(Err(_))`. /// /// Note that `poll_ready` may reserve shared resources that are consumed in a subsequent /// invocation of `call`. Thus, it is critical for implementations to not assume that `call` /// will always be invoked and to ensure that such resources are released if the service is /// dropped before `call` is invoked or the future returned by `call` is dropped before it /// is polled. fn poll_ready(&mut self, cx: &mut Context


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3