2828use arrow:: util:: pretty:: pretty_format_batches;
2929use datafusion:: error:: Result ;
3030use datafusion:: execution:: SendableRecordBatchStream ;
31- use datafusion:: physical_plan:: DedicatedExecutor ;
31+ use datafusion:: physical_plan:: { dedicated_executor , DedicatedExecutor } ;
3232use datafusion:: prelude:: * ;
3333use futures:: stream:: StreamExt ;
3434use object_store:: http:: HttpBuilder ;
@@ -172,6 +172,7 @@ async fn different_runtime_advanced() -> Result<()> {
172172
173173 let http_store = DedicatedExecutor :: wrap_object_store ( http_store) ;
174174
175+ // Tell datafusion about processing http:// urls with this wrapped object store
175176 ctx. register_object_store ( & base_url, http_store) ;
176177
177178 // Plan (and execute) the query on the dedicated runtime
@@ -184,19 +185,28 @@ async fn different_runtime_advanced() -> Result<()> {
184185 . await ?;
185186 let stream: SendableRecordBatchStream = df. execute_stream ( ) . await ?;
186187
187- Ok ( stream) as Result < SendableRecordBatchStream >
188+ Ok ( stream) as Result < _ >
188189 } ) . await ??;
189190
190- // We have now planned the query on the dedicated runtime, but we still need to
191- // drive the stream (aka call `next()` to get the results.
191+ // We have now planned the query on the dedicated runtime, Yay! but we still need to
192+ // drive the stream (aka call `next()` to get the results) .
192193
193- // as mentioned above, calling `next()` (including indirectly by using
194- // FlightDataEncoder to convert the results to flight to send it over the
195- // network), will *still* result in the CPU work (and a bunch of spawned
196- // tasks) being done on the runtime calling next() (aka the current runtime)
197- // and not on the dedicated runtime.
198-
199- // to drive the stream on the dedicated runtime, we need to wrap it using a XXX stream function
194+ // However, as mentioned above, calling `next()` resolves the Stream (and
195+ // any work it may do) on a thread in the current (default) runtime.
196+ //
197+ // To drive the stream on the dedicated runtime, we need to wrap it using a
198+ // `DedicatedExecutor::wrap_stream` stream function
199+ //
200+ // Note if you don't do this you will likely see a panic about `No IO runtime registered.`
201+ // because the threads in the current (main) tokio runtime have not had the IO runtime
202+ // installed
203+ let mut stream = dedicated_executor. run_sendable_record_batch_stream ( stream) ;
204+
205+ // Note you can run other streams on the DedicatedExecutor as well using the
206+ // DedicatedExecutor:YYYXXX function. This is helpful for example, if you
207+ // need to do non trivial CPU work on the results of the stream (e.g.
208+ // calling a FlightDataEncoder to convert the results to flight to send it
209+ // over the network),
200210
201211 while let Some ( batch) = stream. next ( ) . await {
202212 println ! ( "{}" , pretty_format_batches( & [ batch?] ) . unwrap( ) ) ;
0 commit comments