Rust hyper与bb8和postgres的用法示例

Rust hyper与bb8和postgres的用法示例,rust,connection-pooling,rust-tokio,hyper,Rust,Connection Pooling,Rust Tokio,Hyper,我想与和一起使用。在每个请求中,我都希望从池中获取一个新连接。有人能给我举一些这个场景的例子吗? 目前我是这样做的: fn main(){ 让addr=“127.0.0.1:3000”; 让pg_经理= PostgresConnectionManager::新建(“postgresql://auth:auth@本地主机:5433/auth”,NoTls); rt::运行(未来::懒惰(移动| |){ 池::生成器() .建造(pg_经理) .map_err(| e | eprintln!(“数据

我想与和一起使用。在每个请求中,我都希望从池中获取一个新连接。有人能给我举一些这个场景的例子吗? 目前我是这样做的:

fn main(){
让addr=“127.0.0.1:3000”;
让pg_经理=
PostgresConnectionManager::新建(“postgresql://auth:auth@本地主机:5433/auth”,NoTls);
rt::运行(未来::懒惰(移动| |){
池::生成器()
.建造(pg_经理)
.map_err(| e | eprintln!(“数据库错误:{},e))
.然后|移动|池|{
let service=| | service_fn(| req |路由器(req,pool.clone());
让server=server::bind(&addr)
.发球(发球)
.map_err(| e | eprintln!(“服务器错误:{},e));
println!(“在http://{}上侦听”,addr);
服务器
})
}))
}
fn路由器(
_请求:,
_水池:水池,
)->结果{
//用游泳池做一些工作人员
}
但它不会编译:

错误[E0597]:'pool'的寿命不够长
-->src/main.rs:22:63
|
22 | let service=| | service_fn(| req |路由器(req,pool.clone());
|                               -- -----------------------------^^^^----------
|                               |  |                            |
|| |借来的价值不够长久
||返回此值需要借用“pool”作为“static”`
|这里捕获的值
...
30 |             })
|-‘pool’是在借的时候掉在这里的

我做错了什么?如何使我的案例正确运行?

解决方案非常简单,但为了理解问题,我想提供一些附加信息

  • 当您对future调用
    和_-then
    以获得结果时,它会将变量的值传递给传递给
    和_-then
    的闭包,从而获得该数据的所有权

  • hypers builder上的方法
    service
    (由
    Server::bind
    返回)期望闭包具有静态生存期

  • 现在要解决这个问题:

    • 好:将闭包的值传递到服务中,这会移动它,转移所有权
    • 好:
      service\u fn
      是在
      和_then
      闭包之外定义的,因此函数的寿命足够长
    • 错误:闭包使用局部变量池将其传递给
      服务\u fn
    要解决此问题,只需将本地数据移动到闭包中,如下所示:

    let service=move | | service | fn(| req | router(req,pool))

    找到解决方案

    最简单的解决方案如下所示:

    fn main(){
    让addr=“127.0.0.1:3000”;
    让pg_经理=
    PostgresConnectionManager::新建(“postgresql://auth:auth@本地主机:5433/auth”,NoTls);
    rt::运行(未来::懒惰(移动| |){
    池::生成器()
    .建造(pg_经理)
    .map_err(| | eprintln!(“kek”))
    .然后|移动|池|{
    让服务=移动| |{
    让pool=pool.clone();
    服务(移动|请求|路由器(请求和池))
    };
    让server=server::bind(&addr)
    .发球(发球)
    .map_err(| e | eprintln!(“服务器错误:{},e));
    println!(“在http://{}上侦听”,addr);
    服务器
    })
    }))
    }
    fn路由器(
    _请求:,
    _池:&池,
    )->impl未来{
    //一些职员
    }
    
    也可以使用
    Arc
    Mutex
    rt::run
    之外构建
    服务

    fn main(){
    让addr=“127.0.0.1:3000”;
    让pg_经理=
    PostgresConnectionManager::新建(“postgresql://auth:auth@本地主机:5433/auth”,NoTls);
    让游泳池:弧形=
    Arc::new(Mutex::new(None));
    设pool2=pool.clone();
    让服务=移动| |{
    让pool=pool.clone();
    服务需求(移动需求){
    让locked=pool.lock().unwrap();
    让池=锁定
    .as_ref()
    .expect(“bb8应在hyper之前初始化”);
    路由器(请求,池)
    })
    };
    rt::运行(未来::懒惰(移动| |){
    池::生成器()
    .建造(pg_经理)
    .map_err(| | eprintln!(“kek”))
    .然后|移动|池|{
    *pool2.lock().unwrap()=一些(池);
    让server=server::bind(&addr)
    .发球(发球)
    .map_err(| e | eprintln!(“服务器错误:{},e));
    println!(“在http://{}上侦听”,addr);
    服务器
    })
    }))
    }
    fn路由器(
    _请求:,
    _池:&池,
    )->impl未来{
    //一些职员
    }
    
    您试图在
    服务
    闭包中使用
    变量,这违反了它的生存期。也许你也应该把它移到
    服务中去。@Zefick,你能给我举个例子吗?如果你给每个解决方案都举个例子,那就太酷了。根据我的低锈蚀经验,通过阅读代码更容易理解解决方案。我可以在游乐场示例中提供更多的代码——但它没有r2d2,所以我会进行模拟。但服务器和池实际上并不是hyper和r2d2。