乐趣区

关于rust:libp2prs-v030-版本介绍

v0.3.0 于 4.23 公布,应用 AsyncRead & AsyncWrite来替换咱们的 ReadEx & WriteEx & SplitEx;简化了 Kad/DHT 的实现逻辑。

批改

ReadEx & WriteEx & SplitEx:

最后咱们尝试借助 async-trait 来定义本人 io 操作相干的 Trait,以便更纯正的应用 async/await 的形式来编写代码。

ReadEx 为例大略是上面这样:

#[async_trait]
pub trait ReadEx {async fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>;
}

应用咱们定义的 Trait 的确给咱们带来了一些益处,无需再编写状态机式的代码。雷同的逻辑能够用更容易了解的形式实现;同时也引入了一些问题:

  1. 很难进行读写拆散
    咱们先来看看为什么须要读写拆散,应用 async/await 形式相较于 poll 的形式,失去了一些控制能力,无奈在一个 Future 中同时做多件事,比方咱们这里的读写:
let mut socket = ...;

// poll 形式
fn poll(socket: Pin<&mut Socket>, cx: Context) {match socket.poll_read(cx) {
        Poll::Pending => {
            // 这里就有机会在 poll 中同时解决读写
            socket.poll_write(cx)
        }
        Poll::Ready => {...}
    }
}

// async/await
async fn handle_socket(socket: &mut Socket) {socket.read().await;
    // 这里就没方法在在 read 还没筹备好的时候,持续去执行 write 操作
    // 因为 read & write 都是须要 &mut T 的所以也没方法借助 select 来打到目标
    // let read_fut = socket.read();
    // let write_fut = socket.write();
    // select(read_fut, write_fut).await;
}

鉴于这样的起因,咱们就须要将读写离开来解决。同时读写放在不同的协程中解决,代码逻辑也会更清晰。

要实现读写拆散,当然是须要 Runtime 底层 io 提供反对的,两大 Runtime 营垒提供了不同的实现形式:

  • async-std 以 Clone 的形式达到拆散的目标
  • tokio 则借助 BiLock 实现读写拆散

Clone 的形式当然很好,libp2p-rs 中是分了很多层的,上层给下层提供的 io 有本人的逻辑在外面,这样就会有各种起因让咱们很难实现 Clone,即使咱们付出一些代价实现了 Clone 那也意味着绑定了某个运行时。

借助 BiLock 的形式更通用,这时候 ReadEx 的弊病就浮现了,取得锁之后没方法在底层 io 处于Pending 状态时开释锁,这将导致读写协程之间存在死锁的可能。

鉴于以上起因咱们又定义了 SplitEx,各层向上提供的 io 形象都须要实现 SplitEx,这样能解决问题,但不够优雅还减少了工作量。

2. 无奈很好的向后兼容
Rust 异步编程官网未定义规范的读写 Trait,futures 库中的 AsyncRead & AsyncWrite 能够说是事实上的规范。现存的利用 / 零碎中都是基于 AsyncRead & AsyncWrite 去构建的,现有利用 / 零碎想要切换到 libp2p-rs 就须要做一些批改了,Rust 代码中大多是以泛型参数加上 where 条件的模式限定的,而 Rust 对于这种限定条件的批改往往是牵一动员全身。

代替计划是咱们也能够在 ReadEx 的根底上包装出 AsyncRead,但这须要付出额定的性能开销,当然也不是咱们违心见到的。

3. 无奈复用 futures 库中的一些扩大性能

Kad:

Kad-DHT 协定的实现也做了一些批改。更具体地说,从 Kad 中删除了 re-provide/publish 性能。咱们认为 re-provide/publish 的逻辑属于应用 Kad 的应用程序,而不是 Kad 自身。这样的话,相应地也能简化 Provider/Record 的数据结构,并且在 RecordStore Trait 中减少两个 gc_xxx 办法来别离对 Provider/Record 执行 GC,这是通过跟踪从网络接管到的 Provider/Record 的工夫戳来实现的。请留神,仅对从网络接管到的 provider/record 执行 GC。


Netwarps 由国内资深的云计算和分布式技术开发团队组成,该团队在金融、电力、通信及互联网行业有十分丰盛的落地教训。Netwarps 目前在深圳、北京均设立了研发核心,团队规模 30+,其中大部分为具备十年以上开发教训的技术人员,别离来自互联网、金融、云计算、区块链以及科研机构等业余畛域。
Netwarps 专一于平安存储技术产品的研发与利用,次要产品有去中心化文件系统(DFS)、去中心化计算平台(DCP),致力于提供基于去中心化网络技术实现的分布式存储和分布式计算平台,具备高可用、低功耗和低网络的技术特点,实用于物联网、工业互联网等场景。
公众号:Netwarps

退出移动版