0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

shellでTTL付きのキャッシュをしたい

Last updated at Posted at 2017-05-04

こんな感じ

sleep 3 ; echoの結果を最大5秒間キャッシュしている様子。

cache-ttl-on-sh.gif

キャッシュの実装

実装はこのあたりに置いてある。

TTL付きのキャッシュを実装するにあたり、シェルで実現するならファイルに保存しておいて、作成日時はそのファイルのメタ情報を利用すれば楽。
また、やろうと思えば更新日時と作成日時がどちらも取れるので、細かいTTLの実装も可能。

stat -c %Yコマンドで指定したファイルの最終更新日時のepoch秒を取得できる。
それと現在時刻を比べて指定した時間より経過していたら...という処理を書くことでTTLを実装する。

statを使ってファイルの有効期限判定するには以下のようにする。

$ touch -d '1day ago' hoge.txt
$ [ $(( $(date +%s) - $(stat -c %Y hoge.txt) )) -gt $((60 * 60 * 25)) ] && echo 'true' || echo 'false'
false
$ [ $(( $(date +%s) - $(stat -c %Y hoge.txt) )) -gt $((60 * 60 * 23)) ] && echo 'true' || echo 'false'
true

キャッシュを保存するファイルのパスとTTL、実行するコマンドを渡せるようにするとこんな感じになった。

# TTL的に無効かどうか
function is_too_old() {
  local file=$1
  local ttl=$2 # seconds
  if [ -f $file ]; then
    [ $(( $(date +%s) - $(stat -c %Y "$1") )) -gt $ttl ]
  else
    false
  fi
}

# TTLを考慮して読み出す
function read_from_cache() {
  local cache=$1
  local ttl=$2  # seconds
  local command=$3
  if $(is_too_old $cache $ttl);then
    local result=$(sh -c "$command")
    if [ -z $result ]; then
      return
    else
      echo $result > $cache
    fi
  fi
  cat $cache
}

ちなみにMacだとgnubinを入れる必要がある。
テキスト処理のための標準的なコマンド群の OS X への導入手順 - Qiita

コードを読めばわかるが、例えばgcloud projects listの結果を1日キャッシュするには、

read_from_cache ./cache.txt $((60 * 60 * 24)) "gcloud projects list"

みたいにやれば良い。

"読み込み中"の表示

昔書いた記事に大体ある。
Zshで長い処理をしている間に読込中を表示する - Qiita

loadingコマンドはgithubにおいてある。

読み込み中を表示するあたりの実装はこうなる。

# job制御を無効化してバックグラウンド実行しているプロセスのIDが表示されるのを防ぐ
set +m
# loadingをバックグラウンド実行して表示
loading 1000 &
local loading_pid=$!

# 何か重い処理をする
local result=$(sh -c "$command")

# loadingを消す
kill -INT $loading_pid &>/dev/null
# loadingがkillされるのを待つ
sleep 0.1
# job制御を有効に戻す
set -m

ジョブ制御を無効にしてプロセスIDが表示されてしまうのを防ぐのがポイント。

$ sleep 10000 &  # IDが表示される
[1] 89535
$ kill $!  # IDが表示される
[1]  + terminated  sleep 10000
$ set +m
$ sleep 10000 &  # IDが表示されない
$ kill $!  # IDが表示されない
$ set -m
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?