< 返回版块

yecloud 发表于 2022-07-25 16:40

Tags:redis, 借用, mut

error[E0499]: cannot borrow `con` as mutable more than once at a time
  --> src/main.rs:58:41
   |
49 |     let mut ff = crate::FIXFactory::new(&mut con, &cfg, 1);
   |                                         -------- first mutable borrow occurs here
...
58 |     while let Some(raw_msg) = read_list(&mut con, &cfg.LIST_S).expect("<Redis error> ") {
   |                                         ^^^^^^^^ second mutable borrow occurs here
...
69 |                             ff.ping(_v).expect("<Redis error> ");
   |                             ----------- first borrow later used here

以上是错误内容,原因是我用了一个连接变量con,同时用于接受(brpop)和发送(lpush)

49行第一次借用con用于建立发送Factory

58行起了一个无限循环来读con

然后在上面的循环里面又借用了con来企图发送,也就是69行那个ping,这也是出错的最后一次借用

rust不允许重复借用&mut这个原理我理解,是怕“争用”。但是我这个现实case是brpop弹出一条记录后才会lpush,由于redis队列本身的机制导致我其实无法实际去“争用”。因此无论以前用哪种语言写的类似程序我都是一个连接又收又发。

现在rust这样限制,我是不是得再开一个发送专用连接会比较好?就做成全双工这样了?

评论区

写评论
ruby 2022-07-26 20:20

上连接池吧,例如 bb8-redis,每次从池获取可变引用的连接去查询。bb8 池会自动管理链接创建销毁的

作者 yecloud 2022-07-25 17:59

明白您的意思了 我现在的Factory本身有个con的成员,就相当于绑定了一个ff实例了。您的意思是ff.ping的参数里面把&con传过去。 我再考虑下,有可能做成全双工的灵活性更好。

--
👇
Aya0wind: Rust对于同时要进行收发的模型(例如线程队列)一般封装一个Sender和一个Receiver,底层复用同一个来方便双方都能拥有这个连接。
不过我想你这种情况并不需要这样,一个socket连接本来就不应该被多方拥有,你要做的应该是修改设计,比如Factory并不借用conn,等到你要发送的时候再把连接的借用作为参数传进去更好。能否说明一下你的Factory之后是如何使用这个conn的?

Aya0wind 2022-07-25 17:14

Rust对于同时要进行收发的模型(例如线程队列)一般封装一个Sender和一个Receiver,底层复用同一个来方便双方都能拥有这个连接。
不过我想你这种情况并不需要这样,一个socket连接本来就不应该被多方拥有,你要做的应该是修改设计,比如Factory并不借用conn,等到你要发送的时候再把连接的借用作为参数传进去更好。能否说明一下你的Factory之后是如何使用这个conn的?

1 共 3 条评论, 1 页