В теле футуры, которая спавнится? Потому что мне важно чтобы лок произошел 100% на следующей строчке после tokio::spawn, а не когда там экзекьютор запустит футуру
Поэтому было-бы логичнее сначала ждать пока writer отпустит лок, а потом уже запускать консумеров
Мне считай нужно Arc<Notify> и делать notify.notify_waiters() Ты же не ждешь пока tokio:;spawn доработает? Зачем его иначе так запускать. Мне вот тоже нужно запустить в работу долгую таску (долгую это прямо минуты - часы) и каким консьюмерам нужно - те будут ждать окончания, чтобы что-то сделать (залогировать что закончилось, перезапустить или еще что-то)
Сделать обёртку над tokio::sync::broadcast::Receiver . async fn get(rx: &mut Receiver<T>) -> T { loop { match rx.recv().await { Ok(v) => return v, Err(Lagged(_)) => {} }} Ну и длину канала в 1, чтобы stale туда не попадало
Но у меня нет гарантии, что после Lagged данные не поменялись. Мне нужно чтобы при recv().await данные внутри новые не пришли
А как размер 1 поможет от этого?
Получили Lagged, если до следующего вызова recv() пришли новые данные, то опять получим Lagged. Так что возвращаться будет только действительно последнее значение.
Да, но мне нужно на момент регистрации ожидающим (как только я встал в лок recv()) чтобы данные нельзя было менять пока я не получу именно те, за которыми я встал. Проще говоря мне нужны данные именно от того эксклюзивного лока, после которого я встал в очередь
А то иначе это выклядит как использование mutex, что я встал в лок, но мне так и не отдали возможность их прочитать, потому что они опять встали в обработку эксклюзивную
То есть обычный rwlock, но нужно гарантировать, что reader'ы не заблокируют его до первого write?
Да. Обработка должна стартовать сразу для reader’ов, чтобы не получилось прочитать через read пустые данные, хотя таска номинально стартовала в обработку
Сейчас это кастомный тип с двумя Notify и AtomicUsize которые просто будят в нужный момент либо эксклюзивный лок, либо все шаренные локи
Обсуждают сегодня