Skip to main content

risingwave_stream/executor/
wrapper.rs

1// Copyright 2022 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use futures::future::Either;
16
17use crate::executor::prelude::*;
18
19mod epoch_check;
20mod epoch_provide;
21mod schema_check;
22mod stream_node_metrics;
23mod trace;
24mod update_check;
25mod watermark_check;
26
27/// [`WrapperExecutor`] will do some sanity checks and logging for the wrapped executor.
28pub struct WrapperExecutor {
29    input: Executor,
30    actor_ctx: ActorContextRef,
31}
32
33impl WrapperExecutor {
34    pub fn new(input: Executor, actor_ctx: ActorContextRef) -> Self {
35        Self { input, actor_ctx }
36    }
37
38    #[expect(clippy::let_and_return)]
39    fn wrap_debug(
40        info: Arc<ExecutorInfo>,
41        stream: impl MessageStream + 'static,
42    ) -> impl MessageStream + 'static {
43        // Update check
44        let stream = update_check::update_check(info.clone(), stream);
45        // Watermark check
46        let stream = watermark_check::watermark_check(info, stream);
47
48        stream
49    }
50
51    fn wrap(
52        info: Arc<ExecutorInfo>,
53        actor_ctx: ActorContextRef,
54        stream: impl MessageStream + 'static,
55    ) -> BoxedMessageStream {
56        // -- Shared wrappers --
57
58        // Schema check
59        let stream = schema_check::schema_check(info.clone(), stream);
60        // Epoch check
61        let stream = epoch_check::epoch_check(info.clone(), stream);
62
63        // Epoch provide
64        let stream = epoch_provide::epoch_provide(stream);
65
66        // Trace
67        let stream = trace::trace(info.clone(), actor_ctx.clone(), stream);
68
69        // operator-level metrics
70        let stream = stream_node_metrics::stream_node_metrics(info.clone(), stream, actor_ctx);
71
72        // -- Debug-only wrappers --
73        let stream = if cfg!(debug_assertions) {
74            Either::Left(Self::wrap_debug(info.clone(), stream))
75        } else {
76            Either::Right(stream)
77        };
78
79        // Await tree
80        // This should be the last wrapper, so that code in other wrappers are also instrumented with
81        // the span of the current executor.
82        trace::instrument_await_tree(info, stream).boxed()
83    }
84}
85
86impl Execute for WrapperExecutor {
87    fn execute(self: Box<Self>) -> BoxedMessageStream {
88        let info = Arc::new(self.input.info().clone());
89        Self::wrap(info, self.actor_ctx, self.input.execute()).boxed()
90    }
91}