servers/
request_memory_limiter.rs1use std::sync::Arc;
18
19use common_memory_manager::{MemoryGuard, MemoryManager, OnExhaustedPolicy, PermitGranularity};
20use snafu::{IntoError, ResultExt};
21
22use crate::error::{MemoryLimitExceededSnafu, Result};
23use crate::request_memory_metrics::RequestMemoryMetrics;
24
25#[derive(Clone)]
30pub struct ServerMemoryLimiter {
31 manager: Arc<MemoryManager<RequestMemoryMetrics>>,
32 policy: OnExhaustedPolicy,
33}
34
35impl Default for ServerMemoryLimiter {
36 fn default() -> Self {
38 Self::new(0, OnExhaustedPolicy::default())
39 }
40}
41
42impl ServerMemoryLimiter {
43 pub fn new(total_bytes: u64, policy: OnExhaustedPolicy) -> Self {
50 let manager = Arc::new(MemoryManager::with_granularity(
51 total_bytes,
52 PermitGranularity::Kilobyte,
53 RequestMemoryMetrics,
54 ));
55
56 Self { manager, policy }
57 }
58
59 pub async fn acquire(&self, bytes: u64) -> Result<MemoryGuard<RequestMemoryMetrics>> {
61 self.manager
62 .acquire_with_policy(bytes, self.policy)
63 .await
64 .context(MemoryLimitExceededSnafu)
65 }
66
67 pub fn try_acquire(&self, bytes: u64) -> Option<MemoryGuard<RequestMemoryMetrics>> {
69 self.manager.try_acquire(bytes)
70 }
71
72 pub(crate) fn check_request_fits(&self, bytes: u64, held_bytes: u64) -> Result<()> {
74 let requested_bytes = held_bytes.checked_add(bytes);
75 let limit_bytes = self.limit_bytes();
76 match requested_bytes {
77 Some(bytes) if limit_bytes == 0 || bytes <= limit_bytes => Ok(()),
78 _ => Err(MemoryLimitExceededSnafu.into_error(
79 common_memory_manager::Error::MemoryLimitExceeded {
80 requested_bytes: requested_bytes.unwrap_or(u64::MAX),
81 limit_bytes,
82 },
83 )),
84 }
85 }
86
87 pub(crate) fn policy(&self) -> OnExhaustedPolicy {
88 self.policy
89 }
90
91 pub fn limit_bytes(&self) -> u64 {
93 self.manager.limit_bytes()
94 }
95
96 pub fn used_bytes(&self) -> u64 {
98 self.manager.used_bytes()
99 }
100}