#async-channel #pipeline #heavy #task #message #receiver #tokio

relaxed_channel

异步-channel包装器,在重管道上性能更优

2个不稳定版本

0.2.0 2024年3月17日
0.1.0 2023年11月8日

#950 in 异步

Download history 131/week @ 2024-03-16 9/week @ 2024-03-23 18/week @ 2024-03-30 1/week @ 2024-05-18 1/week @ 2024-05-25

59 每月下载量

LGPL-3.0-only

14KB
141

relaxed_channel

异步-channel包装器,在重管道上性能更优

Crates.io License

问题

当读者(持有 Receiver)比作者(持有 Sender)快时,通道的长度将始终较低。通常,在读取一条消息后,一个读者任务会在尝试读取下一条消息时遇到空通道,并立即将自己设置为等待唤醒,以便在下一条消息发送时被唤醒。这意味着在发送下一条消息时,作者必须花费大量时间在tokio运行时标记接收任务唤醒。

(当管道变得重时,这个时间部分是显著的,大约每秒数百万条消息。)

随着读者数量的增加,这种影响也会增加(因为需要唤醒的读者更多),所以接收端的并行性要求越高,作者(或多个作者)的速度就越慢。

解决方案

在读取消息并遇到空通道时

  • 通道为空 => 这意味着我们处理速度比作者生成数据的速度快。
  • 不要浪费读者的时间,而是不是标记自己等待唤醒,而是睡眠,例如100ms。
  • 100ms后,执行正常的 Receiver::recv() 检查消息,只有在这个时候才标记自己等待唤醒,如果仍然没有可用的消息。

这意味着每个读者最多每100ms被作者唤醒一次。

这个crate提供了 RelaxedReceiver,它包装了常规的 async_channel::Receiver 以添加此行为。

请注意,这种设计使得所有读者可能同时睡眠100ms,因此为了不降低读者的速度,通道的容量必须足够大,可以容纳在那段时间内可能到达的更多消息。

依赖项

~3–4MB
~67K SLoC