@@ -452,21 +452,34 @@ def _apply_stream_groups(self, streams: List[AbstractStream]) -> None:
452452 if stream_name :
453453 stream_name_to_group [stream_name ] = group_name
454454
455- # Validate no stream shares a group with its parent streams
455+ # Validate no stream shares a group with any of its ancestor streams
456+ stream_name_to_instance : Dict [str , AbstractStream ] = {s .name : s for s in streams }
457+
458+ def _collect_all_ancestor_names (stream_name : str ) -> Set [str ]:
459+ """Recursively collect all ancestor stream names."""
460+ ancestors : Set [str ] = set ()
461+ inst = stream_name_to_instance .get (stream_name )
462+ if not isinstance (inst , DefaultStream ):
463+ return ancestors
464+ router = inst .get_partition_router ()
465+ if isinstance (router , GroupingPartitionRouter ):
466+ router = router .underlying_partition_router
467+ if not isinstance (router , SubstreamPartitionRouter ):
468+ return ancestors
469+ for parent_config in router .parent_stream_configs :
470+ parent_name = parent_config .stream .name
471+ ancestors .add (parent_name )
472+ ancestors .update (_collect_all_ancestor_names (parent_name ))
473+ return ancestors
474+
456475 for stream in streams :
457476 if not isinstance (stream , DefaultStream ) or stream .name not in stream_name_to_group :
458477 continue
459- partition_router = stream .get_partition_router ()
460- if isinstance (partition_router , GroupingPartitionRouter ):
461- partition_router = partition_router .underlying_partition_router
462- if not isinstance (partition_router , SubstreamPartitionRouter ):
463- continue
464478 group_name = stream_name_to_group [stream .name ]
465- for parent_config in partition_router .parent_stream_configs :
466- parent_name = parent_config .stream .name
467- if stream_name_to_group .get (parent_name ) == group_name :
479+ for ancestor_name in _collect_all_ancestor_names (stream .name ):
480+ if stream_name_to_group .get (ancestor_name ) == group_name :
468481 raise ValueError (
469- f"Stream '{ stream .name } ' and its parent stream '{ parent_name } ' "
482+ f"Stream '{ stream .name } ' and its parent stream '{ ancestor_name } ' "
470483 f"are both in group '{ group_name } '. "
471484 f"A child stream must not share a group with its parent to avoid deadlock."
472485 )
0 commit comments