微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

rust actix:如何在单个连接中异步处理请求?

如何解决rust actix:如何在单个连接中异步处理请求?

我想在单个 http 连接服务器中实现这样的行为 接收多个请求,处理它们,然后按完成顺序将响应传回。

这是actix代码

select gr.firstname,gr.lastname,gr.group_name 
from tbl_Participants gr inner join tbl_Group gr2 
ON gr.group_name = gr2.group_name 
order by group_name

我用 import LadyInGrass from '../../../assets/images/lady_in_grass.jpg'; <imagebackground style={styles.imageStyle} source={imageSource ?? LadyInGrass}> </imagebackground> 测试:

#[derive(Deserialize,Debug)]
struct NumberToProcess {
    x: f64,job_id: u64,}

#[derive(Serialize,Debug)]
struct ProcessResult {
    x: f64,started: String,elapsed_ms: u64,}

#[post("/sqrt")]
async fn my_sqrt(req: web::Json<NumberToProcess>) -> impl Responder {

    let date = Local::Now();
    let started = time::Instant::Now();
    trace!("New task: {:?}",req);

    let mut rng = rand::thread_rng();

    /* some heavy computations */
    let f = req.x;
    thread::sleep(time::Duration::from_millis(rng.gen_range(2000u64,4000u64)));
    let r = f.sqrt();
    /* heavy computations end */

    let res = ProcessResult {
        x: r,job_id: req.job_id,started: date.format("%Y.%m.%d %H:%M:%s").to_string(),elapsed_ms: started.elapsed().as_millis() as u64,};

    HttpResponse::Ok().json(res)
}

问题在于请求是按顺序同步处理的。

结果是:

netcat

是否可以让 actix(或其他一些 Web 框架)在不等待的情况下处理请求 在同一连接内完成前一个请求?

解决方法

您实现的一个问题是 std::thread::sleep阻止异步上下文的执行;相反,您应该使用 tokio@0.2tokio::time::delay_for(...).await yield 执行。如果您确实打算使用 std::thread::sleep模拟阻塞计算,那么您应该使用类似 tokio::spawn_blocking 的东西,这样您就不会阻塞其他请求的处理。

... 并且响应按完成顺序传回。

您使用 netcat 所做的是一个 HTTP 流水线示例。即使请求是并发处理的,您也始终会按照请求的顺序获得响应。

如果您希望它们按完成顺序返回,您要么必须发出单独的请求,要么使用提供 HTTP/2 多路复用的客户端。这可以通过最新的 curl 命令完成:

$ curl -Z \
-d '{"x":1.5,"job_id":1000}' -H 'Content-Type: application/json' -X POST http://localhost:8080/sqrt --next \
-d '{"x":2.5,"job_id":1001}' -H 'Content-Type: application/json' -X POST http://localhost:8080/sqrt --next \
-d '{"x":3.5,"job_id":1002}' -H 'Content-Type: application/json' -X POST http://localhost:8080/sqrt --next \
-d '{"x":4.5,"job_id":1003}' -H 'Content-Type: application/json' -X POST http://localhost:8080/sqrt
{"x":1.224744871391589,"job_id":1000,"started":"2021.05.31 16:32:41","elapsed_ms":2406}
{"x":1.8708286933869707,"job_id":1002,"started":"2021.05.31 16:32:44","elapsed_ms":2631}
{"x":2.1213203435596424,"job_id":1003,"elapsed_ms":2717}
{"x":1.5811388300841898,"job_id":1001,"elapsed_ms":3065}

连接作为第一个请求的一部分升级,所以第一个是同步的,而后面的请求都是并行的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。