Skip to main content

linera_storage_runtime/
common_options.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use linera_storage::{StorageCacheConfig, DEFAULT_CLEANUP_INTERVAL_SECS};
5use linera_views::lru_prefix_cache::StorageCacheConfig as ViewsStorageCacheConfig;
6#[cfg(feature = "rocksdb")]
7use {linera_views::rocks_db::RocksDbStatisticsLevel, std::str::FromStr as _};
8
9/// Command-line options shared by all storage backends, controlling concurrency
10/// limits and cache sizes.
11#[derive(Clone, Debug, clap::Parser)]
12pub struct CommonStorageOptions {
13    /// The maximal number of simultaneous queries to the database
14    #[arg(long, global = true)]
15    pub storage_max_concurrent_queries: Option<usize>,
16
17    /// The maximal memory used in the storage cache.
18    #[arg(long, default_value = "10000000", global = true)]
19    pub storage_max_cache_size: usize,
20
21    /// The maximal size of a value entry in the storage cache.
22    #[arg(long, default_value = "1000000", global = true)]
23    pub storage_max_value_entry_size: usize,
24
25    /// The maximal size of a find-keys entry in the storage cache.
26    #[arg(long, default_value = "1000000", global = true)]
27    pub storage_max_find_keys_entry_size: usize,
28
29    /// The maximal size of a find-key-values entry in the storage cache.
30    #[arg(long, default_value = "1000000", global = true)]
31    pub storage_max_find_key_values_entry_size: usize,
32
33    /// The maximal number of entries in the storage cache.
34    #[arg(long, default_value = "1000", global = true)]
35    pub storage_max_cache_entries: usize,
36
37    /// The maximal memory used in the value cache.
38    #[arg(long, default_value = "10000000", global = true)]
39    pub storage_max_cache_value_size: usize,
40
41    /// The maximal memory used in the find_keys_by_prefix cache.
42    #[arg(long, default_value = "10000000", global = true)]
43    pub storage_max_cache_find_keys_size: usize,
44
45    /// The maximal memory used in the find_key_values_by_prefix cache.
46    #[arg(long, default_value = "10000000", global = true)]
47    pub storage_max_cache_find_key_values_size: usize,
48
49    /// The maximal number of entries in the blob cache.
50    #[arg(long, default_value = "1000", global = true)]
51    pub blob_cache_size: usize,
52
53    /// The maximal number of entries in the confirmed block cache.
54    #[arg(long, default_value = "1000", global = true)]
55    pub confirmed_block_cache_size: usize,
56
57    /// The maximal number of entries in the assembled certificate cache.
58    #[arg(long, default_value = "1000", global = true)]
59    pub certificate_cache_size: usize,
60
61    /// The maximal number of entries in the raw certificate cache.
62    #[arg(long, default_value = "1000", global = true)]
63    pub certificate_raw_cache_size: usize,
64
65    /// The maximal number of entries in the event cache.
66    #[arg(long, default_value = "1000", global = true)]
67    pub event_cache_size: usize,
68
69    /// The maximal number of entries in the block-hash-by-height cache.
70    #[arg(long, default_value = "1000", global = true)]
71    pub block_hash_by_height_cache_size: usize,
72
73    /// The maximal number of entries in the event-block-height cache.
74    #[arg(long, default_value = "1000", global = true)]
75    pub event_block_height_cache_size: usize,
76
77    /// Interval in seconds between weak reference cleanup sweeps in value caches.
78    #[arg(long, default_value_t = DEFAULT_CLEANUP_INTERVAL_SECS, global = true)]
79    pub cache_cleanup_interval_secs: u64,
80
81    /// The replication factor for the keyspace
82    #[arg(long, default_value = "1", global = true)]
83    pub storage_replication_factor: u32,
84
85    /// Enable RocksDB's internal statistics collection and export them as Prometheus
86    /// metrics. Off by default; enable it on nodes whose metrics are scraped.
87    #[cfg(feature = "rocksdb")]
88    #[arg(long, global = true)]
89    pub rocksdb_enable_statistics: bool,
90
91    /// The level of detail collected when `--rocksdb-enable-statistics` is set. Higher
92    /// levels collect more, and more expensive, data. One of: `disable-all`,
93    /// `except-histogram-or-timers`, `except-timers`, `except-detailed-timers`,
94    /// `except-time-for-mutex`, `all`.
95    #[cfg(feature = "rocksdb")]
96    #[arg(
97        long,
98        default_value = "except-histogram-or-timers",
99        value_parser = RocksDbStatisticsLevel::from_str,
100        global = true
101    )]
102    pub rocksdb_statistics_level: RocksDbStatisticsLevel,
103}
104
105impl CommonStorageOptions {
106    /// Returns the options with their default values.
107    pub fn with_defaults() -> Self {
108        use clap::Parser as _;
109        Self::parse_from(std::iter::empty::<String>())
110    }
111
112    /// Builds the storage cache configuration from these options.
113    pub fn storage_cache_config(&self) -> StorageCacheConfig {
114        StorageCacheConfig {
115            blob_cache_size: self.blob_cache_size,
116            confirmed_block_cache_size: self.confirmed_block_cache_size,
117            certificate_cache_size: self.certificate_cache_size,
118            certificate_raw_cache_size: self.certificate_raw_cache_size,
119            event_cache_size: self.event_cache_size,
120            block_hash_by_height_cache_size: self.block_hash_by_height_cache_size,
121            event_block_height_cache_size: self.event_block_height_cache_size,
122            cache_cleanup_interval_secs: self.cache_cleanup_interval_secs,
123        }
124    }
125
126    /// Builds the views storage cache configuration from these options.
127    pub fn views_storage_cache_config(&self) -> ViewsStorageCacheConfig {
128        ViewsStorageCacheConfig {
129            max_cache_size: self.storage_max_cache_size,
130            max_value_entry_size: self.storage_max_value_entry_size,
131            max_find_keys_entry_size: self.storage_max_find_keys_entry_size,
132            max_find_key_values_entry_size: self.storage_max_find_key_values_entry_size,
133            max_cache_entries: self.storage_max_cache_entries,
134            max_cache_value_size: self.storage_max_cache_value_size,
135            max_cache_find_keys_size: self.storage_max_cache_find_keys_size,
136            max_cache_find_key_values_size: self.storage_max_cache_find_key_values_size,
137        }
138    }
139}
140
141#[cfg(all(test, feature = "rocksdb"))]
142mod tests {
143    use clap::Parser as _;
144    use linera_views::rocks_db::RocksDbStatisticsLevel;
145
146    use super::CommonStorageOptions;
147
148    #[test]
149    fn statistics_disabled_by_default() {
150        let options = CommonStorageOptions::with_defaults();
151        assert!(!options.rocksdb_enable_statistics);
152        assert_eq!(
153            options.rocksdb_statistics_level,
154            RocksDbStatisticsLevel::ExceptHistogramOrTimers,
155        );
156    }
157
158    #[test]
159    fn parses_enable_flag_and_level() {
160        let options = CommonStorageOptions::parse_from([
161            "test",
162            "--rocksdb-enable-statistics",
163            "--rocksdb-statistics-level",
164            "all",
165        ]);
166        assert!(options.rocksdb_enable_statistics);
167        assert_eq!(
168            options.rocksdb_statistics_level,
169            RocksDbStatisticsLevel::All
170        );
171    }
172
173    #[test]
174    fn rejects_unknown_level() {
175        assert!(CommonStorageOptions::try_parse_from([
176            "test",
177            "--rocksdb-statistics-level",
178            "not-a-level",
179        ])
180        .is_err());
181    }
182}