Skip to content

Commit

Permalink
refactor: enhance file and tinyufo cache
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Dec 16, 2024
1 parent eb97a4d commit c602154
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 24 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
run: cargo fmt --all -- --check
- name: Run cargo clippy
run: |
cargo install typos-cli
make lint
make lint-full
- name: Run cargo test
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
lint:
typos
cargo clippy --all-targets --all -- --deny=warnings
lint-full:
typos
cargo clippy --features=full --all-targets --all -- --deny=warnings

fmt:
Expand Down
1 change: 1 addition & 0 deletions conf/pingap.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ sentry = ""
auto_restart_check_interval = "1m"

# the file cache directory, cache will use memory if cache directory none (default none)
# cache_directory = "/opt/pingap-cache?reading_max=1000&writing_max=500&cache_max=100"
cache_directory = ""

# the max cache size (default 100mb)
Expand Down
2 changes: 2 additions & 0 deletions src/acme/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ mod tests {

#[test]
fn test_cert() {
// spellchecker:off
let pem = r###"-----BEGIN CERTIFICATE-----
MIID/TCCAmWgAwIBAgIQJUGCkB1VAYha6fGExkx0KTANBgkqhkiG9w0BAQsFADBV
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExFTATBgNVBAsMDHZpY2Fu
Expand All @@ -169,6 +170,7 @@ CCB2C+8hgRNG9ZmW1KU8rxkzoddHmSB8d6+vFqOajxGdyOV+aX00k3w6FgtHOoKD
Ztdj1N0eTfn02pibVcXXfwESPUzcjERaMAGg1hoH1F4Gxg0mqmbySAuVRqNLnXp5
CRVQZGgOQL6WDg3tUUDXYOs=
-----END CERTIFICATE-----"###;
// spellchecker:on
let cert = Certificate::new(pem.to_string(), "".to_string()).unwrap();

assert_eq!(
Expand Down
64 changes: 49 additions & 15 deletions src/cache/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

use super::http_cache::{CacheObject, HttpCacheStats, HttpCacheStorage};
use super::{Error, Result};
use super::{Error, Result, PAGE_SIZE};
#[cfg(feature = "full")]
use crate::state::{CACHE_READING_TIME, CACHE_WRITING_TIME};
use crate::util;
Expand Down Expand Up @@ -43,11 +43,17 @@ pub struct FileCache {
cache: Option<TinyUfo<String, CacheObject>>,
}

/// Create a file cache and use tinyufo for hotspot data caching
pub fn new_file_cache(dir: &str) -> Result<FileCache> {
struct FileCacheParams {
directory: String,
reading_max: u32,
writing_max: u32,
cache_max: usize,
}

fn parse_params(dir: &str) -> FileCacheParams {
let mut reading_max = 10 * 1000;
let mut writing_max = 1000;
let mut cache_size = 100;
let mut cache_max = 100;
let dir = if let Some((dir, query)) = dir.split_once('?') {
let m = util::convert_query_map(query);
if let Some(max) = m.get("reading_max") {
Expand All @@ -56,31 +62,50 @@ pub fn new_file_cache(dir: &str) -> Result<FileCache> {
if let Some(max) = m.get("writing_max") {
writing_max = max.parse::<u32>().unwrap_or(writing_max);
}
if let Some(value) = m.get("cache_size") {
cache_size = value.parse::<usize>().unwrap_or(cache_size);
if let Some(value) = m.get("cache_max") {
cache_max = value.parse::<usize>().unwrap_or(cache_max);
}
util::resolve_path(dir)
} else {
util::resolve_path(dir)
};
let path = Path::new(&dir);
FileCacheParams {
directory: dir,
reading_max,
writing_max,
cache_max,
}
}

/// Create a file cache and use tinyufo for hotspot data caching
pub fn new_file_cache(dir: &str) -> Result<FileCache> {
let params = parse_params(dir);

let path = Path::new(&params.directory);
if !path.exists() {
std::fs::create_dir_all(path).map_err(|e| Error::Io { source: e })?;
}
info!(dir, reading_max, writing_max, "new file cache");
info!(
dir = params.directory,
reading_max = params.reading_max,
writing_max = params.writing_max,
cache_max = params.cache_max,
"new file cache"
);
let mut cache = None;
if cache_size > 0 {
cache = Some(TinyUfo::new(cache_size, cache_size));
if params.cache_max > 0 {
cache =
Some(TinyUfo::new(params.cache_max, params.cache_max * PAGE_SIZE));
}

Ok(FileCache {
directory: dir,
directory: params.directory,
reading: AtomicU32::new(0),
reading_max,
reading_max: params.reading_max,
#[cfg(feature = "full")]
read_time: CACHE_READING_TIME.clone(),
writing: AtomicU32::new(0),
writing_max,
writing_max: params.writing_max,
#[cfg(feature = "full")]
write_time: CACHE_WRITING_TIME.clone(),
cache,
Expand Down Expand Up @@ -138,7 +163,6 @@ impl HttpCacheStorage for FileCache {
if let Some(c) = &self.cache {
c.put(key.clone(), data.clone(), weight);
}

#[cfg(feature = "full")]
let start = SystemTime::now();
let buf: Bytes = data.into();
Expand Down Expand Up @@ -215,13 +239,23 @@ impl HttpCacheStorage for FileCache {

#[cfg(test)]
mod tests {
use super::new_file_cache;
use super::{new_file_cache, parse_params};
use crate::cache::http_cache::{CacheObject, HttpCacheStorage};
use bytes::Bytes;
use pretty_assertions::assert_eq;
use std::time::{Duration, SystemTime};
use tempfile::TempDir;

#[test]
fn test_parse_params() {
let params = parse_params(
"~/pingap?reading_max=1000&writing_max=500&cache_max=100",
);
assert_eq!(1000, params.reading_max);
assert_eq!(500, params.writing_max);
assert_eq!(100, params.cache_max);
}

#[tokio::test]
async fn test_file_cache() {
let dir = TempDir::new().unwrap();
Expand Down
16 changes: 9 additions & 7 deletions src/cache/http_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use super::file;
use super::{Error, Result};
use super::{file, Error, Result, PAGE_SIZE};
use crate::service::CommonServiceTask;
use crate::service::ServiceTask;
use async_trait::async_trait;
Expand Down Expand Up @@ -274,14 +273,17 @@ impl HandleMiss for ObjectMissHandler {
}
}

// 40MB
static MAX_ONE_CACHE_SIZE: usize = 10 * 1024 * PAGE_SIZE;

fn get_wegiht(size: usize) -> u16 {
if size < 50 * 1024 {
return 4;
if size <= PAGE_SIZE {
return 1;
}
if size < 500 * 1024 {
return 2;
if size >= MAX_ONE_CACHE_SIZE {
return u16::MAX;
}
1
(size / PAGE_SIZE) as u16
}

#[async_trait]
Expand Down
4 changes: 3 additions & 1 deletion src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ mod file;
mod http_cache;
mod tiny;

pub static PAGE_SIZE: usize = 4096;

#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display("Io error: {source}"))]
Expand All @@ -39,7 +41,7 @@ impl From<Error> for pingora::BError {

pub fn new_tiny_ufo_cache(size: usize) -> HttpCache {
HttpCache {
cached: Arc::new(tiny::new_tiny_ufo_cache(size / 1024, size / 1024)),
cached: Arc::new(tiny::new_tiny_ufo_cache(size / PAGE_SIZE, size)),
}
}
pub fn new_file_cache(dir: &str) -> Result<HttpCache> {
Expand Down
4 changes: 4 additions & 0 deletions src/config/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,7 @@ mod tests {

#[test]
fn test_validate_cert() {
// spellchecker:off
let pem = r#"-----BEGIN CERTIFICATE-----
MIIEljCCAv6gAwIBAgIQeYUdeFj3gpzhQes3aGaMZTANBgkqhkiG9w0BAQsFADCB
pTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMT0wOwYDVQQLDDR4aWVz
Expand Down Expand Up @@ -1097,6 +1098,7 @@ IZpXa00xvlnm1BOHOfRI4Ehlfa5jmfcdnrGkQLGjiyygQtKcc7rOXGK+mSeyxwhs
sIARwslSQd4q0dbYTPKvvUHxTYiCv78vQBAsE15T2GGS80pAFDBW9vOf3upANvOf
EHjKf0Dweb4ppL4ddgeAKU5V0qn76K2fFaE=
-----END CERTIFICATE-----"#;
// spellchecker:on
let result = validate_cert(pem);
assert_eq!(true, result.is_ok());

Expand Down Expand Up @@ -1284,6 +1286,7 @@ EHjKf0Dweb4ppL4ddgeAKU5V0qn76K2fFaE=

#[test]
fn test_certificate_conf() {
// spellchecker:off
let pem = r#"-----BEGIN CERTIFICATE-----
MIIEljCCAv6gAwIBAgIQeYUdeFj3gpzhQes3aGaMZTANBgkqhkiG9w0BAQsFADCB
pTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMT0wOwYDVQQLDDR4aWVz
Expand Down Expand Up @@ -1339,6 +1342,7 @@ K+hM90AVD1xmU7mxy3EDPwzjK1wZTj7u0fvcAtZJztIfL+lmVpkvK8KDLQ9wCWE7
SGToOzVHYX7VazxioA9nhNne9kaixvnIUg3iowAz07J7o6EU8tfYsnHxsvjlIkBU
ai02RHnemmqJaNepfmCdyec=
-----END PRIVATE KEY-----"#;
// spellchecker:on
let conf = CertificateConf {
tls_cert: Some(pem.to_string()),
tls_key: Some(key.to_string()),
Expand Down
9 changes: 8 additions & 1 deletion src/plugin/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use bytesize::ByteSize;
use fancy_regex::Regex;
use http::{Method, StatusCode};
use humantime::parse_duration;
use memory_stats::memory_stats;
use once_cell::sync::{Lazy, OnceCell};
use pingora::cache::eviction::simple_lru::Manager;
use pingora::cache::eviction::EvictionManager;
Expand Down Expand Up @@ -79,8 +80,14 @@ fn get_cache_backend() -> Result<&'static HttpCache> {
message: e.to_string(),
})?
} else {
// max memory
let max_memory = if let Some(value) = memory_stats() {
value.physical_mem / 2
} else {
ByteSize::gb(4).as_u64() as usize
};
// tiny ufo cache
new_tiny_ufo_cache(size.min(ByteSize::gb(1).as_u64() as usize))
new_tiny_ufo_cache(size.min(max_memory))
};
Ok(cache)
})
Expand Down
2 changes: 2 additions & 0 deletions src/proxy/dynamic_certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ mod tests {
use std::collections::HashMap;

fn get_tls_pem() -> (String, String) {
// spellchecker:off
(
r###"-----BEGIN CERTIFICATE-----
MIID/TCCAmWgAwIBAgIQJUGCkB1VAYha6fGExkx0KTANBgkqhkiG9w0BAQsFADBV
Expand Down Expand Up @@ -577,6 +578,7 @@ aqcrKJfS+xaKWxXPiNlpBMG5
-----END PRIVATE KEY-----"###
.to_string(),
)
// spellchecker:on
}

#[test]
Expand Down
8 changes: 8 additions & 0 deletions typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[default]
extend-ignore-re = [
"(?Rm)^.*(#|//)\\s*spellchecker:disable-line$",
"(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
]

[files]
extend-exclude = ["*.md", "*.toml"]

0 comments on commit c602154

Please sign in to comment.