glean_core/upload/
policy.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Policies for ping storage, uploading and requests.
6
7use malloc_size_of_derive::MallocSizeOf;
8
9const MAX_RECOVERABLE_FAILURES: u32 = 3;
10const MAX_WAIT_ATTEMPTS: u32 = 3;
11const MAX_PING_BODY_SIZE: usize = 1024 * 1024; // 1 MB
12const MAX_PENDING_PINGS_DIRECTORY_SIZE: u64 = 10 * 1024 * 1024; // 10MB
13
14// The average number of baseline pings per client (on Fenix) is at 15 pings a day.
15// The P99 value is ~110.
16// With a maximum of (a nice round) 250 we can store about 2 days worth of pings.
17// A baseline ping file averages about 600 bytes, so that's a total of just 144 kB we store.
18// With the default rate limit of 15 pings per 60s it would take roughly 16 minutes to send out all pending
19// pings.
20const MAX_PENDING_PINGS_COUNT: u64 = 250;
21
22/// A struct holding the values for all the policies related to ping storage, uploading and requests.
23#[derive(Debug, MallocSizeOf)]
24pub struct Policy {
25    /// The maximum recoverable failures allowed per uploading window.
26    ///
27    /// Limiting this is necessary to avoid infinite loops on requesting upload tasks.
28    max_recoverable_failures: Option<u32>,
29    /// The maximum of [`PingUploadTask::Wait`] responses a user may get in a row
30    /// when calling [`get_upload_task`].
31    ///
32    /// Limiting this is necessary to avoid infinite loops on requesting upload tasks.
33    max_wait_attempts: Option<u32>,
34    /// The maximum size in bytes a ping body may have to be eligible for upload.
35    max_ping_body_size: Option<usize>,
36    /// The maximum size in byte the pending pings directory may have on disk.
37    max_pending_pings_directory_size: Option<u64>,
38    /// The maximum number of pending pings on disk.
39    max_pending_pings_count: Option<u64>,
40}
41
42impl Default for Policy {
43    fn default() -> Self {
44        Policy {
45            max_recoverable_failures: Some(MAX_RECOVERABLE_FAILURES),
46            max_wait_attempts: Some(MAX_WAIT_ATTEMPTS),
47            max_ping_body_size: Some(MAX_PING_BODY_SIZE),
48            max_pending_pings_directory_size: Some(MAX_PENDING_PINGS_DIRECTORY_SIZE),
49            max_pending_pings_count: Some(MAX_PENDING_PINGS_COUNT),
50        }
51    }
52}
53
54impl Policy {
55    pub fn max_recoverable_failures(&self) -> u32 {
56        match &self.max_recoverable_failures {
57            Some(v) => *v,
58            None => u32::MAX,
59        }
60    }
61
62    #[cfg(test)]
63    pub fn set_max_recoverable_failures(&mut self, v: Option<u32>) {
64        self.max_recoverable_failures = v;
65    }
66
67    pub fn max_wait_attempts(&self) -> u32 {
68        match &self.max_wait_attempts {
69            Some(v) => *v,
70            None => u32::MAX,
71        }
72    }
73
74    #[cfg(test)]
75    pub fn set_max_wait_attempts(&mut self, v: Option<u32>) {
76        self.max_wait_attempts = v;
77    }
78
79    pub fn max_ping_body_size(&self) -> usize {
80        match &self.max_ping_body_size {
81            Some(v) => *v,
82            None => usize::MAX,
83        }
84    }
85
86    #[cfg(test)]
87    pub fn set_max_ping_body_size(&mut self, v: Option<usize>) {
88        self.max_ping_body_size = v;
89    }
90
91    pub fn max_pending_pings_directory_size(&self) -> u64 {
92        match &self.max_pending_pings_directory_size {
93            Some(v) => *v,
94            None => u64::MAX,
95        }
96    }
97
98    pub fn max_pending_pings_count(&self) -> u64 {
99        match &self.max_pending_pings_count {
100            Some(v) => *v,
101            None => u64::MAX,
102        }
103    }
104
105    #[cfg(test)]
106    pub fn set_max_pending_pings_directory_size(&mut self, v: Option<u64>) {
107        self.max_pending_pings_directory_size = v;
108    }
109
110    #[cfg(test)]
111    pub fn set_max_pending_pings_count(&mut self, v: Option<u64>) {
112        self.max_pending_pings_count = v;
113    }
114}