risingwave_stream/common/
rate_limit.rs1use futures_async_stream::stream;
16use risingwave_common::array::StreamChunk;
17use risingwave_common_rate_limit::{RateLimit, RateLimiter};
18
19pub(crate) fn limited_chunk_size(rate_limit_burst: Option<u32>) -> usize {
21 let config_chunk_size = crate::config::chunk_size();
22 rate_limit_burst
23 .map(|burst| config_chunk_size.min(burst as usize))
24 .unwrap_or(config_chunk_size)
25}
26
27#[stream(item = StreamChunk)]
30pub(crate) async fn rate_limited_pieces(limiter: &RateLimiter, chunk: StreamChunk) {
31 if chunk.capacity() == 0 {
32 yield chunk;
33 return;
34 }
35 let rate_limit = loop {
36 match limiter.rate_limit() {
37 RateLimit::Pause => limiter.wait(0).await,
38 limit => break limit,
39 }
40 };
41 match rate_limit {
42 RateLimit::Pause => unreachable!(),
43 RateLimit::Disabled => yield chunk,
44 RateLimit::Fixed(limit) => {
45 let max_permits = limit.get();
46 if chunk.rate_limit_permits() <= max_permits {
47 limiter.wait(chunk.rate_limit_permits()).await;
48 yield chunk;
49 } else {
50 for piece in chunk.split(max_permits as _) {
51 limiter.wait_chunk(&piece).await;
52 yield piece;
53 }
54 }
55 }
56 }
57}