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_no_initial_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 = !inputs.is_empty()
68 && match node.get_upstream_dispatcher_type()? {
69 DispatcherType::Unspecified => unreachable!(),
70 DispatcherType::Hash | DispatcherType::Broadcast => false,
71 DispatcherType::Simple => false,
73 DispatcherType::NoShuffle => true,
75 };
76
77 let upstreams = if always_single_input {
78 MergeExecutorUpstream::Singleton(Itertools::exactly_one(inputs.into_iter()).unwrap())
79 } else {
80 MergeExecutorUpstream::Merge(MergeExecutor::new_merge_upstream(
81 inputs,
82 &executor_stats,
83 &actor_context,
84 chunk_size,
85 info.schema.clone(),
86 ))
87 };
88
89 Ok(Some(MergeExecutorInput::new(
90 upstreams,
91 actor_context,
92 upstream_fragment_id,
93 local_barrier_manager,
94 executor_stats,
95 info,
96 )))
97 }
98}
99
100impl_stream_node_body!(Merge(MergeNode) => MergeExecutorBuilder);
101
102impl ExecutorBuilder for MergeExecutorBuilder {
103 type Node = MergeNode;
104
105 async fn new_boxed_executor(
106 params: ExecutorParams,
107 node: &Self::Node,
108 _store: impl StateStore,
109 ) -> StreamResult<Executor> {
110 let actor_id = params.actor_context.id;
111 let fragment_id = params.actor_context.fragment_id;
112 let barrier_rx = params.local_barrier_manager.subscribe_barrier(actor_id);
113 Ok(Self::new_input(
114 params.local_barrier_manager,
115 params.executor_stats,
116 params.actor_context,
117 params.info,
118 node,
119 params.config.developer.chunk_size,
120 )
121 .await?
122 .ok_or_else(|| {
123 anyhow!(
124 "no upstream actors found for actor {} in fragment {}",
125 actor_id,
126 fragment_id
127 )
128 })?
129 .into_executor(barrier_rx))
130 }
131}