🈁

Deno Cache API ファイル フォルダ ディレクトリ ない どこ 探し方

2023/03/21に公開

TL;DR

  • Windowsは"%TMP%\deno_cache"にある。
  • Windows以外は"/tmp/deno_cache"にある。
  • ない場合はRustのstd::env::temp_dirを読む。

ない

最近ようやくHonoのMiddlewareを使いまくるようになったのですが、Denoでも使えるCache Middlewareを使い始めたところ、Windowsのローカル開発環境で突然コードを編集しても反映されない問題が発生したので調べてみました。
どうやらHonoのCache MiddlewareはCache APIを使っているらしく、Denoではv1.26から追加されたわりと新し目の機能です。

https://hono.dev/middleware/builtin/cache
https://developer.mozilla.org/en-US/docs/Web/API/Cache
https://github.com/denoland/deno/releases/tag/v1.26.0

とりあえずdeno run-rオプションつけたり、DENO_DIRの中にあるファイル全部消したり、ChromeやEdgeのキャッシュを無効化すれば解消するだろうと思いやってみても全く変わらず、そもそもcurlでGETしても編集前の内容が返ってきます。
わりと新し目の機能なので、なぜこうなるのかググっても出てこないし、deno infoでも表示されず、Denoの公式ドキュメントやリポジトリにも説明がありません。

https://github.com/denoland/deno/tree/main/ext/cache

どこ

色々調べた結果、週刊Denoの内容にヒントがありました。

https://uki00a.github.io/deno-weekly/articles/deno/v1.26.html

localStorageなどと同様にSQLiteをベースに実装されており、利用する際は特にパーミッションなどは要求されません。
ただし、localStorageとは異なり、DENO_DIRではなく/tmp/deno_cacheにSQLiteのデータベースやキャッシュされたコンテンツなどが保存されます。

なるほど/tmpディレクトリ。
ではWindowsも環境変数%TMP%に設定してあるパスを見に行けば……。

> cd "%TMP%"
> dir
...
 C:\Users\hono\AppData\Local\Temp のディレクトリ

2023/03/21  00:55    <DIR>          .
2023/03/21  00:55    <DIR>          ..
...
2023/03/21  00:55    <DIR>          deno_cache
...

あった。
こんなんわかるか!!

普通にエクスプローラー上で選択した後、Deleteキーを押して削除してもよいのですが、異なる作業ディレクトリからコマンドプロンプト上で消すにはrdコマンドを使います。

> rd /s "%TMP%\deno_cache"
C:\Users\hono\AppData\Local\Temp\deno_cache、よろしいですか (Y/N)?

yまたはYを押すとdeno_cacheフォルダと中にあるファイル・フォルダを全部消してくれます。
%TMP%=%TEMP%であれば%TEMP%でも構いません。

でもいちいち質問されたり消さないといけないのは面倒ですね。
もし環境変数%TMP%にあるパスが一時ファイルで間違いない自信満々な方は以下のコマンドを使いましょう。

> echo y | rd /s "%TMP%\deno_cache"

Windows以外ではLinuxで見慣れたrm -rfコマンドを/tmpディレクトリに使います。

$ rm -rf /tmp/deno_cache

また、deno taskに組み込めばLinuxで見慣れたrm -rfコマンドをWindowsでも使うことができます。
この場合Windowsでも削除してよいか質問されることはありません。

deno.json
{
  "tasks": {
    "start": "rm -rf $TMP\\deno_cache && deno run --allow-net server.ts"
  }
}

ただstartタスクにrm -rfコマンドを組み込んだWebアプリケーションを配布するのはよくないですね。
次のようにcleanタスクあたりに分けたほうがいいかもしれません。

deno.json
{
  "tasks": {
    "start": "deno run --allow-net server.ts",
    "clean": "rm -rf $TMP\\deno_cache"
  }
}

これだとLinuxでは使えないですね。

deno.json
{
  "tasks": {
    "start": "deno run --allow-net server.ts",
    "clean": "rm -rf /tmp/deno_cache",
    "windows:clean": "rm -rf $TMP\\deno_cache"
  }
}

ヨシ!

探し方

さて、色々調べても出てこなかったこのdeno_cache、一体どうやって作られているのでしょうか?
Denoのソースコードを検索してもそれっぽい/tmpディレクトリや環境変数%TMP%はありません。

そこでDeno v1.26のリリースノートにある"feat: implement Web Cache API (#15829)"から該当のプルリクエストを読むことにしました。

https://github.com/denoland/deno/pull/15829

これかな?

https://github.com/denoland/deno/pull/15829#pullrequestreview-1110949513

Rustのstd::env::temp_dirから参照しているようです。
Rustなにもわからないので公式ドキュメントを確認します。

https://doc.rust-lang.org/std/env/fn.temp_dir.html

Unixでは、環境変数TMPDIRが設定されていればその値を、そうでなければAndroid以外では/tmpを返します。Androidでは、グローバルなテンポラリフォルダが存在しないため(通常はアプリごとに割り当てられる)、/data/local/tmpが返されます。Windowsでは、この関数が内部的に使用しているGetTempPath2 / GetTempPathと同等の動作となります。なお、これは将来的に変更される可能性があります。
www.DeepL.com/Translator(無料版)で翻訳しました。

Windows以外は大体理解しました。
Windowsの「GetTempPath2 / GetTempPathと同等」というのがよくわからないので確認します。

https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a

GetTempPath2(GetTempPath)関数は、次の順序で環境変数の存在を確認し、最初に見つかったパスを使用します。
・TMP環境変数で指定されたパス。
・TEMP環境変数で指定されたパス。
・USERPROFILE環境変数で指定されたパス。
・Windowsのディレクトリ。
www.DeepL.com/Translator(無料版)で翻訳しました。

deno_cache完全に理解した。

大事なことなので

  • Windowsは"%TMP%\deno_cache"にある。
  • Windows以外は"/tmp/deno_cache"にある。
  • ない場合はRustのstd::env::temp_dirを読む。
> deno --version
deno 1.31.3 (release, x86_64-pc-windows-msvc)
v8 11.0.226.19
typescript 4.9.4

Discussion