1313use std:: collections:: HashMap ;
1414use std:: sync:: { Arc , OnceLock , RwLock } ;
1515
16- use anyhow:: { Context , Result , anyhow, bail} ;
16+ use anyhow:: { Context , Result , anyhow, bail, ensure } ;
1717use tokio:: sync:: mpsc;
1818use tokio_stream:: wrappers:: ReceiverStream ;
1919use tracing:: { error, info, warn} ;
@@ -330,40 +330,52 @@ impl JobManager {
330330 operators : & [ ChainedOperator ] ,
331331 edge_manager : & mut EdgeManager ,
332332 ) -> Result < PhysicalPipeline > {
333- let ( raw_inboxes, raw_outboxes) = edge_manager. take_endpoints ( pipeline_id) ;
333+ let ( raw_inboxes, raw_outboxes) =
334+ edge_manager. take_endpoints ( pipeline_id) . with_context ( || {
335+ format ! (
336+ "Failed to retrieve network endpoints for pipeline {}" ,
337+ pipeline_id
338+ )
339+ } ) ?;
334340
335- let physical_outboxes = raw_outboxes
341+ let physical_outboxes: Vec < PhysicalSender > = raw_outboxes
336342 . into_iter ( )
337343 . map ( PhysicalSender :: Local )
338344 . collect ( ) ;
345+
339346 let physical_inboxes: Vec < BoxedEventStream > = raw_inboxes
340347 . into_iter ( )
341348 . map ( |rx| Box :: pin ( ReceiverStream :: new ( rx) ) as _ )
342349 . collect ( ) ;
343350
344- let chain = self . build_operator_chain ( operators) ?;
345-
346- if chain. source . is_none ( ) && physical_inboxes. is_empty ( ) {
347- bail ! (
348- "Topology Error: pipeline '{}' contains no source and no upstream inputs." ,
349- pipeline_id
350- ) ;
351- }
352- if chain. source . is_some ( ) && !physical_inboxes. is_empty ( ) {
353- bail ! (
354- "Topology Error: source pipeline '{}' should not have upstream inputs." ,
351+ let chain = self . build_operator_chain ( operators) . with_context ( || {
352+ format ! (
353+ "Failed to build operator chain for pipeline {}" ,
355354 pipeline_id
356- ) ;
357- }
355+ )
356+ } ) ?;
357+
358+ ensure ! (
359+ chain. source. is_some( ) || !physical_inboxes. is_empty( ) ,
360+ "Topology Error: Pipeline '{}' contains no source and has no upstream inputs (Dead end)." ,
361+ pipeline_id
362+ ) ;
363+ ensure ! (
364+ chain. source. is_none( ) || physical_inboxes. is_empty( ) ,
365+ "Topology Error: Source pipeline '{}' cannot have upstream inputs." ,
366+ pipeline_id
367+ ) ;
358368
359369 let ( control_tx, control_rx) = mpsc:: channel ( 64 ) ;
360370 let status = Arc :: new ( RwLock :: new ( PipelineStatus :: Initializing ) ) ;
361371
372+ let subtask_index = 0 ;
373+ let parallelism = 1 ;
362374 let ctx = TaskContext :: new (
363375 job_id. clone ( ) ,
364376 pipeline_id,
365- 0 ,
366- 1 ,
377+ subtask_index ,
378+ parallelism ,
367379 physical_outboxes,
368380 Arc :: clone ( & self . memory_pool ) ,
369381 ) ;
@@ -373,12 +385,15 @@ impl JobManager {
373385 PipelineRunner :: Source ( SourceDriver :: new ( source, chain_head, ctx, control_rx) )
374386 } else {
375387 PipelineRunner :: Standard (
376- Pipeline :: new ( chain. operators , ctx, physical_inboxes, control_rx)
377- . map_err ( |e| anyhow ! ( "Pipeline init failed: {e}" ) ) ?,
388+ Pipeline :: new ( chain. operators , ctx, physical_inboxes, control_rx) . with_context (
389+ || format ! ( "Failed to initialize Standard Pipeline {}" , pipeline_id) ,
390+ ) ?,
378391 )
379392 } ;
380393
381- let handle = self . spawn_worker_thread ( job_id, pipeline_id, runner, Arc :: clone ( & status) ) ?;
394+ let handle = self
395+ . spawn_worker_thread ( job_id, pipeline_id, runner, Arc :: clone ( & status) )
396+ . with_context ( || format ! ( "Failed to spawn OS thread for pipeline {}" , pipeline_id) ) ?;
382397
383398 Ok ( PhysicalPipeline {
384399 pipeline_id,
0 commit comments