Denoで保存されている/tmp/deno_cacheに何が保管されているか気になる
6 min read
こんにちは、無能です。
前回の記事で/tmp/deno_cache
にキャッシュが保管されていることがわかりましたが何を保存しているのか気になったので見てみる。
SQLiteで保存されている
まずは/tmp/deno_cache
に移動してみます。
cd /tmp/deno_cache
ls
7b52928d182b91e3d058c899022fc32b63d560748054c3143d70a24863f0f2ba
cd 7b52928d182b91e3d058c899022fc32b63d560748054c3143d70a24863f0f2ba
ls -la
合計 120
drwxrwxr-x 3 haturatu haturatu 4096 10月 10 21:58 .
drwxrwxr-x 3 haturatu haturatu 4096 10月 10 21:58 ..
drwxrwxr-x 3 haturatu haturatu 4096 10月 10 21:58 1
-rw-r--r-- 1 haturatu haturatu 4096 10月 10 21:58 cache_metadata.db
-rw-r--r-- 1 haturatu haturatu 32768 10月 10 22:02 cache_metadata.db-shm
-rw-r--r-- 1 haturatu haturatu 70072 10月 10 22:02 cache_metadata.db-wal
どうやらこの感じはSQLite
で保存している様子。なので接続してみましょう。
sqlite> .tables
cache_storage request_response_list
sqlite> select * from cache_storage;
1|lume_remote_files
sqlite> select * from request_response_list;
1|1|https://cdn.jsdelivr.net/npm/svg2png-wasm@1.4.1/svg2png_wasm_bg.wasm||access-control-allow-origin
*
access-control-expose-headers
*
timing-allow-origin
*
cache-control
public, max-age=31536000, s-maxage=31536000, immutable
cross-origin-resource-policy
cross-origin
~~省略~~~
max-age=31536000; includeSubDomains; preload
x-content-type-options
nosniff
server
cloudflare
|200|OK|5f1e6f823db55b21ff1e048860bbbce7b104fe57fa3a4449ce36989784625f32|1728565376
sqlite>
じゃあdeno_cache/01_cache.js
あたりから深堀して見てみよう
alleycat:[haturatu]:~/git/deno/ext/cache$ ls -la
合計 60
drwxr-xr-x 2 haturatu haturatu 4096 10月 12 18:16 .
drwxr-xr-x 24 haturatu haturatu 4096 10月 12 18:16 ..
-rw-r--r-- 1 haturatu haturatu 9048 10月 12 18:16 01_cache.js
-rw-r--r-- 1 haturatu haturatu 491 10月 12 18:16 Cargo.toml
-rw-r--r-- 1 haturatu haturatu 1043 10月 12 18:16 README.md
-rw-r--r-- 1 haturatu haturatu 2042 10月 12 18:16 lib.deno_cache.d.ts
-rw-r--r-- 1 haturatu haturatu 9827 10月 12 18:16 lib.rs
-rw-r--r-- 1 haturatu haturatu 12666 10月 12 18:16 sqlite.rs
alleycat:[haturatu]:~/git/deno/ext/cache$ cat Cargo.toml
# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
[package]
name = "deno_cache"
version = "0.103.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
readme = "README.md"
repository.workspace = true
description = "Implementation of Cache API for Deno"
[lib]
path = "lib.rs"
[dependencies]
async-trait.workspace = true
deno_core.workspace = true
rusqlite.workspace = true
serde.workspace = true
sha2.workspace = true
tokio.workspace = true
alleycat:[haturatu]:~/git/deno/ext/cache$ grep "tmp" ./*
alleycat:[haturatu]:~/git/deno/ext/cache$ grep "deno_cache" ./*
./Cargo.toml:name = "deno_cache"
./README.md:# deno_cache
./lib.rs:deno_core::extension!(deno_cache,
alleycat:[haturatu]:~/git/deno/ext/cache$ cat lib.rs
~~~
deno_core::extension!(deno_cache,
deps = [ deno_webidl, deno_web, deno_url, deno_fetch ],
parameters=[CA: Cache],
ops = [
op_cache_storage_open<CA>,
op_cache_storage_has<CA>,
op_cache_storage_delete<CA>,
op_cache_put<CA>,
op_cache_match<CA>,
op_cache_delete<CA>,
],
esm = [ "01_cache.js" ],
options = {
maybe_create_cache: Option<CreateCache<CA>>,
},
state = |state, options| {
if let Some(create_cache) = options.maybe_create_cache {
state.put(create_cache);
}
},
);
~~~
alleycat:[haturatu]:~/git/deno/ext/cache$ grep " op_cache_storage" ./*
./01_cache.js: op_cache_storage_delete,
./01_cache.js: op_cache_storage_has,
./01_cache.js: op_cache_storage_open,
./01_cache.js: const cacheId = await op_cache_storage_open(cacheName);
./01_cache.js: return await op_cache_storage_has(cacheName);
./01_cache.js: return await op_cache_storage_delete(cacheName);
./lib.rs: op_cache_storage_open<CA>,
./lib.rs: op_cache_storage_has<CA>,
./lib.rs: op_cache_storage_delete<CA>,
./lib.rs:pub async fn op_cache_storage_open<CA>(
./lib.rs:pub async fn op_cache_storage_has<CA>(
./lib.rs:pub async fn op_cache_storage_delete<CA>(
alleycat:[haturatu]:~/git/deno/ext/cache$ grep "cacheName" ./*
./01_cache.js: async open(cacheName) {
./01_cache.js: cacheName = webidl.converters["DOMString"](cacheName, prefix, "Argument 1");
./01_cache.js: const cacheId = await op_cache_storage_open(cacheName);
./01_cache.js: async has(cacheName) {
./01_cache.js: cacheName = webidl.converters["DOMString"](cacheName, prefix, "Argument 1");
./01_cache.js: return await op_cache_storage_has(cacheName);
./01_cache.js: async delete(cacheName) {
./01_cache.js: cacheName = webidl.converters["DOMString"](cacheName, prefix, "Argument 1");
./01_cache.js: return await op_cache_storage_delete(cacheName);
./lib.deno_cache.d.ts: open(cacheName: string): Promise<Cache>;
./lib.deno_cache.d.ts: has(cacheName: string): Promise<boolean>;
./lib.deno_cache.d.ts: delete(cacheName: string): Promise<boolean>;
sqlite.rs
を見てみます。
alleycat:[haturatu]:~/git/deno/ext/cache$ grep "cache_storage_dir" ./*
./sqlite.rs: pub cache_storage_dir: PathBuf,
./sqlite.rs: pub fn new(cache_storage_dir: PathBuf) -> Self {
./sqlite.rs: std::fs::create_dir_all(&cache_storage_dir)
./sqlite.rs: let path = cache_storage_dir.join("cache_metadata.db");
./sqlite.rs: cache_storage_dir,
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: let responses_dir = get_responses_dir(cache_storage_dir, cache_id);
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: let cache_dir = cache_storage_dir.join(cache_id.to_string());
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: get_responses_dir(cache_storage_dir, request_response.cache_id);
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: get_responses_dir(cache_storage_dir, request.cache_id)
./sqlite.rs:fn get_responses_dir(cache_storage_dir: PathBuf, cache_id: i64) -> PathBuf {
./sqlite.rs: cache_storage_dir
alleycat:[haturatu]:~/git/deno/ext/cache$ head -5 sqlite.rs
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
use std::path::PathBuf;
use std::pin::Pin;
use std::rc::Rc;
alleycat:[haturatu]:~/git/deno$ grep "PathBuf" ./*/* 2>/dev/null | grep -v use
./cli/build.rs: let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
./cli/build.rs: let path_dts = state.borrow::<PathBuf>();
./cli/build.rs: PathBuf::from(op_crate_lib).canonicalize()?
./cli/build.rs: op_crate_libs: HashMap<&'static str, PathBuf>,
./cli/build.rs: path_dts: PathBuf,
./cli/build.rs: pub fn create_compiler_snapshot(snapshot_path: PathBuf, cwd: &Path) {
./cli/build.rs: PathBuf::from(env::var_os("OUT_DIR").unwrap())
~~~
alleycat:[haturatu]:~/git/deno$ cd ./ext/cache/
alleycat:[haturatu]:~/git/deno/ext/cache$ grep let ./* | grep dir
./sqlite.rs: let path = cache_storage_dir.join("cache_metadata.db");
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: let responses_dir = get_responses_dir(cache_storage_dir, cache_id);
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: let cache_dir = cache_storage_dir.join(cache_id.to_string());
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
./sqlite.rs: let responses_dir =
./sqlite.rs: let response_path = responses_dir.join(&body_key);
./sqlite.rs: let cache_storage_dir = self.cache_storage_dir.clone();
alleycat:[haturatu]:~/git/deno/ext/cache$ vim ./sqlite.rs
alleycat:[haturatu]:~/git/deno/ext/cache$ cat ./sqlite.rs
~~~
use std::path::PathBuf;
~~~
#[derive(Clone)]
pub struct SqliteBackedCache {
pub connection: Arc<Mutex<Connection>>,
pub cache_storage_dir: PathBuf,
}
~~~
PathBuf
alleycat:[haturatu]:~/git/deno/ext/cache$ cd -
alleycat:[haturatu]:~/git/deno$ grep "let mut" ./*/*/* | grep "PathBuf"
grep: ./cli/bench/fs: ディレクトリです
grep: ./cli/bench/http: ディレクトリです
grep: ./cli/bench/napi: ディレクトリです
grep: ./cli/bench/stdio: ディレクトリです
grep: ./cli/bench/testdata: ディレクトリです
./cli/cache/disk_cache.rs: let mut out = PathBuf::new();
お!
alleycat:[haturatu]:~/git/deno$ cd ./cli/cache/
alleycat:[haturatu]:~/git/deno/cli/cache$ ls -la
合計 136
drwxr-xr-x 2 haturatu haturatu 4096 10月 12 18:16 .
drwxr-xr-x 15 haturatu haturatu 4096 10月 12 18:16 ..
-rw-r--r-- 1 haturatu haturatu 17292 10月 12 18:16 cache_db.rs
-rw-r--r-- 1 haturatu haturatu 3643 10月 12 18:16 caches.rs
-rw-r--r-- 1 haturatu haturatu 5190 10月 12 18:16 check.rs
-rw-r--r-- 1 haturatu haturatu 5668 10月 12 18:16 code_cache.rs
-rw-r--r-- 1 haturatu haturatu 1090 10月 12 18:16 common.rs
-rw-r--r-- 1 haturatu haturatu 8449 10月 12 18:16 deno_dir.rs
-rw-r--r-- 1 haturatu haturatu 7647 10月 12 18:16 disk_cache.rs
-rw-r--r-- 1 haturatu haturatu 7195 10月 12 18:16 emit.rs
-rw-r--r-- 1 haturatu haturatu 4531 10月 12 18:16 fast_check.rs
-rw-r--r-- 1 haturatu haturatu 8367 10月 12 18:16 incremental.rs
-rw-r--r-- 1 haturatu haturatu 12142 10月 12 18:16 mod.rs
-rw-r--r-- 1 haturatu haturatu 7796 10月 12 18:16 module_info.rs
-rw-r--r-- 1 haturatu haturatu 4847 10月 12 18:16 node.rs
-rw-r--r-- 1 haturatu haturatu 4567 10月 12 18:16 parsed_source.rs
alleycat:[haturatu]:~/git/deno/cli/cache$ vim disk_cache.rs
~~~
impl DiskCache {
/// `location` must be an absolute path.
pub fn new(location: &Path) -> Self {
assert!(location.is_absolute());
Self {
location: location.to_owned(),
}
}
fn get_cache_filename(&self, url: &Url) -> Option<PathBuf> {
let mut out = PathBuf::new();
~~~
alleycat:[haturatu]:~/git/deno/cli/cache$ grep "get_cache_filename" ./* | grep "let"
./disk_cache.rs: let base = self.get_cache_filename(url)?;
なんとなくはどこが呼び出されているかは把握できました。
ちなみに前回のエラーが起きるのはおそらくバグなんかではなく、所有権を変えた場合の稀なパターンであり、例えば
which deno
/home/haturatu/.deno/bin/deno
であるときにこのdeno
の実行ユーザはhaturatu
です。
と、これをわざわざ別ユーザの権限で実行し、生成された/tmp/deno_cache
であり他ユーザと衝突を起こしてしまいます。
複数ユーザ間でdeno
コマンドを実行するべきでは無い(必要なパターンを除く)し、これは妥当だと思います。
厳密に行うのであれば、ちゃんとdeno
ユーザを作成しそれでインストールして実行したほうが多分良いですね。
でも気になるとするならば
deno info
をしたときに/tmp/deno_cache
が出力されないことかなあ。
alleycat:[haturatu]:~/git/deno/ext/cache$ deno info
DENO_DIR location: /home/haturatu/.cache/deno
Remote modules cache: /home/haturatu/.cache/deno/deps
npm modules cache: /home/haturatu/.cache/deno/npm
Emitted modules cache: /home/haturatu/.cache/deno/gen
Language server registries cache: /home/haturatu/.cache/deno/registries
Origin storage: /home/haturatu/.cache/deno/location_data
ちょっと気になったのでメモ書き程度に。
それでは。
またよろしくおねがいします。