172 похожих чатов

Всем доброго времени суток. Абстрактно обрисую ситуацию, а далее вопрос.

Есть таска со входящим стримом данных, которая броадкастит данные на клиентов. Как только появляется клиент, я добавляю его в броадкаст. Проблема в том, что на каждый send() мне приходится лочить мьютекс, чего я делать совершенно не хочу по-причине того, что из-за этого мьютекса свич контекста токио - это просто rng. Вопрос таков, можно ли вообще избавиться от этого мьютекса (пример ниже, надеюсь не слишком простыня, чтобы её в плейграунд нести) ?

let (broadcast, _) = tokio::sync::broadcast::channel::<Bytes>(100);
let tx_broadcast = std::sync::Arc::new(std::sync::Mutex::new(broadcast));
let rx_broadcast = tx_broadcast.clone();

tokio::spawn(async move {
while let Some((_, data)) = connection.try_next().await.unwrap() {
tx_broadcast.lock().unwrap().send(data);
}
});

while let Some(Ok(mut socket)) = multiplexer.next().await {
let mut receiver = rx_broadcast.lock().unwrap().subscribe();
tokio::spawn(async move {
let mut stream = stream::unfold(receiver, |mut rx| async move {
loop {
match rx.recv().await {
Ok(data) => {
break Some((Ok((Instant::now(), data)), rx));
}
Err(_) => continue,
}
}
})
.boxed();

socket.send_all(&mut stream).await;
});
}

16 ответов

7 просмотров

"Sender handles are clone-able, allowing concurrent send and receive actions". Arc<Mutex<>> не нужен

Lighty- Автор вопроса
red75prime
"Sender handles are clone-able, allowing concurren...

В шары долблюсь, сори. Спасибо большое, почему то в упор не увидел этого. Ласт вопрос по этому куску кода. Можно ли переписать этот луп красивее ? loop { match rx.recv().await { Ok(data) => { break Some((Ok((Instant::now(), data)), rx)); } Err(_) => continue, } }

Lighty- Автор вопроса
Пух
if let Ok(data) = ...

Я имею в виду без лупа в принципе. Я так понимаю, через while я этого не сделаю ?

Антон 🇦🇲
Не то же

проявить фантазию конечно придется

Lighty
Я имею в виду без лупа в принципе. Я так понимаю, ...

Завернуть в tokio_stream::wrappers::BroadcastStream и .filter_map(Result::ok)

Lighty
Я имею в виду без лупа в принципе. Я так понимаю, ...

может как то вроде такого while let Err(_) = rx.recv().await {} let value = Some((Ok((Instant::now(), rx.recv().await.unwrap())), rx));

Lighty- Автор вопроса
Lighty
Спасибо, попробую.

Да, .boxed() там не особо нужен (если он не для уменьшения размера бинарника, конечно). unfold тоже не будет нужен

Похожие вопросы

Обсуждают сегодня

Комрады, посоветуйте, куда копать? Стал прикручивать кастомизацию тем. В OnShow главной главной формы пытаюсь загрузить из файла настроек и применить тему (на скрине, как долж...
Ed Doc
13
OnShow один раз вызывается? или возможен Hide?
Iluha Companets
14
Такс, блин, таки кто-то знает, каким образом работают макросы stdin/stdout/stderr? Я влез в stdio.h, там определения нет, отладил через асмокод - вызывается функция со странны...
The Bird of Hermes
18
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Всем привет, на линуксе лучше на fasm или nasm учиться писать для начала ?
meszjol
14
Если у меня есть такой класс: Object = {} function Object:new(a_name, a_transform, a_color, a_mesh, a_material, a_shader, a_textures) local private = {} private.n...
Cuarno Vile
4
Гайз, кто-нибудь пробовал запустить probe-rs под камень, которого нет в probe-rs? Мб есть какой-нибудь пример у кого... Через target-gen попробовал сгенерировать chip-descript...
Максим Смирнов
2
А еще в перле можно уже @arr1 + @arr2?
Sergei Zhmylove
53
@sand_witch скорее к тебе вопрос, добавил в .cabal webdriver-w3c и вот такая ошибка от nix develop error: Package ‘script-monad-0.0.4’ in /nix/store/7vdxbra0kwbr0ys0kc5...
Fedor
5
@MrMiscipitlick А можешь макрос написать, который будет вычислять смещение относительно переданных меток? Просто .label1-.label2, и вернуть значение.
КТ315
35
Карта сайта