Filter 配置Rust';s扭曲过滤器

Filter 配置Rust';s扭曲过滤器,filter,rust,rust-warp,Filter,Rust,Rust Warp,我正在尝试设置一个简单的GET过滤器,但在编译时遇到了问题 这是我试图映射到请求的函数: pub async fn get_users(reference_counter: Arc<RwLock<MysqlConnection>>) -> Result<impl Reply, Rejection> { // Get users code here } 编译错误发生在和_then上,它非常神秘,它是这样说的: error[E0599]:在当前作用域

我正在尝试设置一个简单的
GET
过滤器,但在编译时遇到了问题

这是我试图映射到请求的函数:

pub async fn get_users(reference_counter: Arc<RwLock<MysqlConnection>>) -> Result<impl Reply, Rejection> {
   // Get users code here
}
编译错误发生在
和_then
上,它非常神秘,它是这样说的:

error[E0599]:在当前作用域中找不到结构`warp::filter::and::and`的名为`and_then`的方法
-->src\main.rs:21:14
|
21 |和_then(user::get_users);
|在“warp::filter::and::and”中找不到^`
|
::C:\Users\Yasmani\.cargo\registry\src\github.com-1ecc6299db9ec823\warp-0.2.3\src\filter\and.rs:12:1
|
12 |酒吧结构和{
| --------------------
| |
|不满足`\:warp::filter::FilterBase`
|不满足`\:warp::filter::filter::filter`
|
=注意:方法`and_then`存在,但不满足以下特征界限:
`warp::filter::and::and:warp::filter::FilterBase`
这是'warp::filter::and::and:warp::filter::filter::所必需的`
`&warp::filter::and::and:warp::filter::FilterBase`
“&warp::filter::and::and:warp::filter::filter”所需`
`&mut warp::filter::and::and:warp::filter::FilterBase`
`&mut warp::filter::and::and:warp::filter::filter::所需`

我相信这与
ref\u filter
中的闭包返回的类型与函数
get\u users
所期望的类型不匹配有关,但我不确定原因。我相信闭包返回的是
Arc>
,而
get\u users
函数也会返回相同的类型。问题是什么由于某些原因,闭包的返回类型未知。仔细查看编译器错误,闭包的返回类型是
\uu
。这会导致GET筛选器的以下部分的返回类型不是
筛选器
,这反过来意味着未实现

let get_users=warp::get()
和(warp::path(“用户”))
.和(ref_filter.clone())
解决方案 注释闭包的返回类型

let ref_filter=warp::any().map(move | |->Arc{reference_counter.clone());
(也许您会发现
db\u连接的类型与您期望的不同。)

上下文
在我看来,
db\u连接的类型实际上是问题的根源。我试图用空结构或
impl Foo
替换
db\u连接,从而从代码中创建一个MWE,但编译时没有任何问题。

问题是来自Diesel API的
MysqlConnection
没有问题实现Warp API所需的一些
trait
。解决方案是停止在此处直接使用
MysqlConnection
类型,而是使用动态生成连接的
ConnectionPool
ConnectionPool
是Diesel软件包r2d2功能的一部分

现在我想起来了,这很有道理。以前,我使用一个数据库连接来处理所有传入的HTTP请求。这很糟糕,因为应用程序可能会在同一时间对同一个连接执行多个读取操作

下面是处理HTTP请求的函数:

type ConnectionPool = Pool<ConnectionManager<MysqlConnection>>;
type ConnectionLock = RwLock<ConnectionPool>;
type ConnectionLockArc = Arc<ConnectionLock>;

pub async fn get_users(lock: ConnectionLockArc) -> Result<impl Reply, Rejection>{
    let users = storage::get_users(&lock);
    let response = json(&users);
    return Ok(response);
}

我用一个空的
struct
类型尝试了你的实验,得到了同样的结果;它编译得很好。但是,如果我在
struct
中添加一个
MysqlConnection
类型字段,那么一切都会再次中断。看起来每当你在任何地方注入
MysqlConnection
时,都会让Warp API生气。为什么?
MysqlCConnection
就是我从Diesel API中得到的类型。它感觉像是
结构
隐式派生了一些东西(
复制
克隆
,或者其他东西)当它为空时,然后在我将连接添加为字段时停止派生。有什么想法吗?我想出来了。这与
MysqlConnection
没有实现一些
trait
Warp要求有关。确切的
trait
我不知道,但我找到了一种不同的方法。我将发布一个关于如何实现这一点的完整答案。Glad您已经弄明白了@AxiomaticNexus!为什么要使用
rBlock
Arc
?@maxcountryman应用程序本身就是多线程的。
rBlock
防止一个线程在另一个线程写入数据库时对数据库执行读取操作。
Arc
允许跨多个线程共享
rBlock
.
type ConnectionPool = Pool<ConnectionManager<MysqlConnection>>;
type ConnectionLock = RwLock<ConnectionPool>;
type ConnectionLockArc = Arc<ConnectionLock>;

pub async fn get_users(lock: ConnectionLockArc) -> Result<impl Reply, Rejection>{
    let users = storage::get_users(&lock);
    let response = json(&users);
    return Ok(response);
}
#[tokio::main]
async fn main() {
     let pool = storage::establish_connection_pool();
     let lock = RwLock::new(pool);
     let reference = Arc::new(lock);
     let resources = warp::any().map(move || reference.clone());
     let get_users = warp::get()
             .and(warp::path("users"))
             .and(resources.clone())
             .and_then(user::get_users);
     warp::serve(get_users).run(([127, 0, 0, 1], 3030)).await;
 }