Create a stream of all data written to `tx`
(self)
| 120 | |
| 121 | /// Create a stream of all data written to `tx` |
| 122 | pub fn build(self) -> BoxStream<'static, Result<O>> { |
| 123 | let Self { |
| 124 | tx, |
| 125 | rx, |
| 126 | mut join_set, |
| 127 | } = self; |
| 128 | |
| 129 | // Doesn't need tx |
| 130 | drop(tx); |
| 131 | |
| 132 | // future that checks the result of the join set, and propagates panic if seen |
| 133 | let check = async move { |
| 134 | while let Some(result) = join_set.join_next().await { |
| 135 | match result { |
| 136 | Ok(task_result) => { |
| 137 | match task_result { |
| 138 | // Nothing to report |
| 139 | Ok(_) => continue, |
| 140 | // This means a blocking task error |
| 141 | Err(error) => return Some(Err(error)), |
| 142 | } |
| 143 | } |
| 144 | // This means a tokio task error, likely a panic |
| 145 | Err(e) => { |
| 146 | if e.is_panic() { |
| 147 | // resume on the main thread |
| 148 | std::panic::resume_unwind(e.into_panic()); |
| 149 | } else { |
| 150 | // This should only occur if the task is |
| 151 | // cancelled, which would only occur if |
| 152 | // the JoinSet were aborted, which in turn |
| 153 | // would imply that the receiver has been |
| 154 | // dropped and this code is not running |
| 155 | return Some(exec_err!("Non Panic Task error: {e}")); |
| 156 | } |
| 157 | } |
| 158 | } |
| 159 | } |
| 160 | None |
| 161 | }; |
| 162 | |
| 163 | let check_stream = futures::stream::once(check) |
| 164 | // unwrap Option / only return the error |
| 165 | .filter_map(|item| async move { item }); |
| 166 | |
| 167 | // Convert the receiver into a stream |
| 168 | let rx_stream = futures::stream::unfold(rx, |mut rx| async move { |
| 169 | let next_item = rx.recv().await; |
| 170 | next_item.map(|next_item| (next_item, rx)) |
| 171 | }); |
| 172 | |
| 173 | // Merge the streams together so whichever is ready first |
| 174 | // produces the batch |
| 175 | futures::stream::select(rx_stream, check_stream).boxed() |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | /// Builder for `RecordBatchReceiverStream` that propagates errors |