Repository: denoland/deno
File: ext/cache/sqlite.rs (Rust)

Code before:
use rusqlite::OptionalExtension;
use tokio::io::AsyncWrite;
use tokio::io::AsyncWriteExt;

use crate::deserialize_headers;
use crate::get_header;
use crate::serialize_headers;
use crate::vary_header_matches;
use crate::CacheDeleteRequest;
use crate::CacheError;
use crate::CacheMatchRequest;
use crate::CacheMatchResponseMeta;
use crate::CachePutRequest;
use crate::CacheResponseResource;

#[derive(Clone)]
pub struct SqliteBackedCache {
  pub connection: Arc<Mutex<Connection>>,
  pub cache_storage_dir: PathBuf,
}

impl SqliteBackedCache {
  pub fn new(cache_storage_dir: PathBuf) -> Result<Self, CacheError> {
    {
      let env_var_val =
        std::env::var("DENO_CACHE_FORCE_IN_MEMORY").unwrap_or_default();
      let connection = if env_var_val == "1" {
        rusqlite::Connection::open_in_memory()
          .unwrap_or_else(|_| panic!("failed to open in-memory cache db"))
      } else {
        std::fs::create_dir_all(&cache_storage_dir).map_err(|source| {
          CacheError::CacheStorageDirectory {
            dir: cache_storage_dir.clone(),
            source,
          }
        })?;

        let path = cache_storage_dir.join("cache_metadata.db");
        let connection =
          rusqlite::Connection::open(&path).unwrap_or_else(|_| {
            panic!("failed to open cache db at {}", path.display())
          });
        // Enable write-ahead-logging mode.
        let initial_pragmas = "
        -- enable write-ahead-logging mode
        PRAGMA journal_mode=WAL;
        PRAGMA synchronous=NORMAL;
        PRAGMA optimize;
      ";
        connection.execute_batch(initial_pragmas)?;
        connection

Review comment (performance):
I wonder if we should make these enums more of an enum style for better future proofing. Ex. `DENO_CACHE_DB_MODE=memory` or something like that

Code after:
use rusqlite::OptionalExtension;
use tokio::io::AsyncWrite;
use tokio::io::AsyncWriteExt;

use crate::deserialize_headers;
use crate::get_header;
use crate::serialize_headers;
use crate::vary_header_matches;
use crate::CacheDeleteRequest;
use crate::CacheError;
use crate::CacheMatchRequest;
use crate::CacheMatchResponseMeta;
use crate::CachePutRequest;
use crate::CacheResponseResource;

#[derive(Clone)]
pub struct SqliteBackedCache {
  pub connection: Arc<Mutex<Connection>>,
  pub cache_storage_dir: PathBuf,
}

#[derive(Debug)]
enum Mode {
  Disk,
  InMemory,
}

impl SqliteBackedCache {
  pub fn new(cache_storage_dir: PathBuf) -> Result<Self, CacheError> {
    let mode = match std::env::var("DENO_CACHE_DB_MODE")
      .unwrap_or_default()
      .as_str()
    {
      "disk" | "" => Mode::Disk,
      "memory" => Mode::InMemory,
      _ => {
        log::warn!("Unknown DENO_CACHE_DB_MODE value, defaulting to disk");
        Mode::Disk
      }
    };

    let connection = if matches!(mode, Mode::InMemory) {
      rusqlite::Connection::open_in_memory()
        .unwrap_or_else(|_| panic!("failed to open in-memory cache db"))
    } else {
      std::fs::create_dir_all(&cache_storage_dir).map_err(|source| {
        CacheError::CacheStorageDirectory {
          dir: cache_storage_dir.clone(),
          source,
        }
      })?;