SignalVecExt::flatten stops polling after first top-level item if the item is empty
martin-kolarik opened this issue · comments
If the first polled item of flatten is empty SignalVec, inner polling of this SignalVec ends with Pending, and therefore top-level poll loop does not continue. If top-level SignalVec contains more items in this situation, they are not polled immediately and wait until next wake up.
Thanks for the report, but I'm having a hard time reproducing it. Could you give an example which fails?
I apologize, I will provide code later, I am a bit short of time now.
It will be something like (not tested):
let a = MutableVec<MutableVec<u32>>::new();
a.lock_mut().push_cloned(MutableVec::new());
a.lock_mut().push_cloned(MutableVec::new_with_values(vec![15]));
let s = a.signal_vec_cloned().map(|v| v.signal_vec()).flatten();
The behavior in handling Flatten
then is that the first (top-level) VecDiff::Push
is loaded and stored into this.inner
, but then polling stops (my continue
solves it in the proposed fix), so the next VecDiff::Push
carrying vec![15]
is delayed till next wakeup.
So, here is the code:
use std::future::ready;
use async_std::task::{sleep, spawn};
use futures_signals::signal_vec::{MutableVec, SignalVecExt};
#[async_std::main]
async fn main() {
let outer: MutableVec<MutableVec<usize>> = MutableVec::new();
let flattened = outer
.signal_vec_cloned()
.map(|inner| inner.signal_vec())
.flatten();
spawn(flattened.map(|x| println!("{x}")).for_each(|_| ready(())));
sleep(std::time::Duration::from_secs(1)).await;
outer.lock_mut().push_cloned(MutableVec::new());
outer
.lock_mut()
.push_cloned(MutableVec::new_with_values(vec![42]));
loop {
sleep(std::time::Duration::from_secs(1)).await;
}
}
The sleep
afer spawn
ensures in a dirty way that spawn
starts polling before values are inserted.
If flatten
implementation uses continue
, as in #80, it prints out 42
. If flatten
uses false
, as in current 0.3.33 code, it prints out nothing.
Sorry about the delay on this, I've been quite busy. Your example was helpful, and I've fixed this.