risingwave_stream/from_proto/
merge.rs1use std::sync::Arc;
16
17use anyhow::anyhow;
18use futures::future::try_join_all;
19use risingwave_pb::stream_plan::{DispatcherType, MergeNode};
20
21use super::*;
22use crate::executor::exchange::input::new_input;
23use crate::executor::monitor::StreamingMetrics;
24use crate::executor::{ActorContextRef, MergeExecutor, MergeExecutorInput, MergeExecutorUpstream};
25use crate::task::LocalBarrierManager;
26
27pub struct MergeExecutorBuilder;
28
29impl MergeExecutorBuilder {
30 pub(crate) async fn new_input(
31 local_barrier_manager: LocalBarrierManager,
32 executor_stats: Arc<StreamingMetrics>,
33 actor_context: ActorContextRef,
34 info: ExecutorInfo,
35 node: &MergeNode,
36 chunk_size: usize,
37 ) -> StreamResult<Option<MergeExecutorInput>> {
38 let upstream_fragment_id = node.get_upstream_fragment_id();
39 let upstream_actors = actor_context
40 .initial_upstream_actors
41 .get(&upstream_fragment_id);
42 if upstream_actors.is_none() && !node.allow_empty_upstream {
43 return Ok(None);
44 }
45
46 let inputs: Vec<_> = try_join_all(
47 upstream_actors
48 .into_iter()
49 .flat_map(|upstream_actors| upstream_actors.actors.iter())
50 .map(|upstream_actor| {
51 new_input(
52 &local_barrier_manager,
53 executor_stats.clone(),
54 actor_context.id,
55 actor_context.fragment_id,
56 upstream_actor,
57 upstream_fragment_id,
58 actor_context.config.clone(),
59 )
60 }),
61 )
62 .await?;
63
64 let always_single_input = !node.allow_empty_upstream
68 && !inputs.is_empty()
69 && match node.get_upstream_dispatcher_type()? {
70 DispatcherType::Unspecified => unreachable!(),
71 DispatcherType::Hash | DispatcherType::Broadcast => false,
72 DispatcherType::Simple => false,
74 DispatcherType::NoShuffle => true,
76 };
77
78 let upstreams = if always_single_input {
79 MergeExecutorUpstream::Singleton(Itertools::exactly_one(inputs.into_iter()).unwrap())
80 } else {
81 MergeExecutorUpstream::Merge(MergeExecutor::new_merge_upstream(
82 inputs,
83 &executor_stats,
84 &actor_context,
85 chunk_size,
86 info.schema.clone(),
87 ))
88 };
89
90 Ok(Some(MergeExecutorInput::new(
91 upstreams,
92 actor_context,
93 upstream_fragment_id,
94 local_barrier_manager,
95 executor_stats,
96 info,
97 )))
98 }
99}
100
101impl_stream_node_body!(Merge(MergeNode) => MergeExecutorBuilder);
102
103impl ExecutorBuilder for MergeExecutorBuilder {
104 type Node = MergeNode;
105
106 async fn new_boxed_executor(
107 params: ExecutorParams,
108 node: &Self::Node,
109 _store: impl StateStore,
110 ) -> StreamResult<Executor> {
111 let actor_id = params.actor_context.id;
112 let fragment_id = params.actor_context.fragment_id;
113 let barrier_rx = params.local_barrier_manager.subscribe_barrier(actor_id);
114 Ok(Self::new_input(
115 params.local_barrier_manager,
116 params.executor_stats,
117 params.actor_context,
118 params.info,
119 node,
120 params.config.developer.chunk_size,
121 )
122 .await?
123 .ok_or_else(|| {
124 anyhow!(
125 "no upstream actors found for actor {} in fragment {}",
126 actor_id,
127 fragment_id
128 )
129 })?
130 .into_executor(barrier_rx))
131 }
132}