MENU

GASのCacheServiceと保存データの違い

当ページのリンクには広告(PR)が含まれていることがあります。
GASのCacheServiceと保存データの違い。一時的な結果、キャッシュを読む、なければ再取得の処理例。

キャッシュへ入れた値が取れなくなっても、元データが消えたとは限りません。GASのCacheServiceは、何度も計算する値などを一時的に再利用するための仕組みです。受付番号や処理の完了記録のように、失うと困る唯一の保存先には向きません。

公式資料では、保存時に指定した有効期間は目安で、期限より早く削除される場合があると説明されています。取得できなければ元データから作り直せる設計にして、キャッシュがあることを処理の前提にしないようにします。

目次

nullなら元データへ戻る

cache.get(key)の戻り値は文字列かnullです。nullはそのキーの値が見つからない状態で、業務上の集計が0という意味ではありません。空の文字列や数字の0とも区別します。

今回の例は表示用の小さな集計結果をキャッシュします。JSONが壊れている場合や、必要な項目がそろっていない場合も、保存値をそのまま信用せず再計算へ戻します。元データを取得できなければ、0でごまかさずそのエラーを返します。

キャッシュの戻り値と有効期間はCacheの公式資料、共有範囲はCacheServiceで確認できます。

値がなくても動く読み取り関数

読み取り用関数を引数に渡し、キャッシュを使わない場合の動きを分けます。例のキーにv1を入れているのは、計算内容を変えたときに古い形式を使い続けないためです。

function loadPracticeSummary(cache, calculate) {
  const key = 'practice-summary-v1';
  const raw = cache.get(key);
  if (raw !== null) {
    try {
      const value = JSON.parse(raw);
      if (value && Number.isSafeInteger(value.count) && value.count >= 0 &&
          typeof value.total === 'number' && Number.isFinite(value.total)) {
        return {value: value, fromCache: true};
      }
    } catch (error) {
      // 不正な一時データは使わず、元の計算へ進みます。
    }
  }
  const value = calculate();
  if (!value || !Number.isSafeInteger(value.count) || value.count < 0 ||
      typeof value.total !== 'number' || !Number.isFinite(value.total)) {
    throw new Error('再計算の結果を確認してください');
  }
  cache.put(key, JSON.stringify(value), 60);
  return {value: value, fromCache: false};
}

function previewCachedSummary() {
  const cache = CacheService.getUserCache();
  const result = loadPracticeSummary(cache, function () {
    const amounts = [100, 200]; // 架空の練習データです。
    return {count: amounts.length, total: amounts.reduce((a, b) => a + b, 0)};
  });
  console.log(JSON.stringify(result));
}

キャッシュがなければcount:2,total:300,fromCache:falseが想定されます。次に値が残っている間の呼び出しではfromCache:trueになります。60秒は練習用の指定で、その時間いっぱい保存されることを保証するものではありません。

利用者の範囲も選ぶ

getScriptCacheはスクリプトの利用者で共有するキャッシュです。一方、getUserCacheは現在の利用者とスクリプトに対応します。利用者ごとに内容が違う結果を、共通のキーでスクリプトキャッシュへ入れると、別の人へ同じ結果を返す設計になり得ます。

この例は利用者側のキャッシュを選んでいます。ただし、実行する利用者が誰になるかは実行方法に左右されます。Webアプリの実行者設定も確認し、キャッシュの種類だけでアクセス権限を代用しないでください。

データが更新された直後でも、キャッシュが残れば古い計算結果を返します。表示の古さを許容する時間を決めるか、元データのバージョンをキーへ含めるなど、更新との対応を考えます。正確な受付状態を判断する用途では、元の保存先を読みます。

永続的な設定とは分ける

APIの設定値などを保存する方法はPropertiesServiceで扱っています。キャッシュはなくても作り直せる情報、正式なデータは失わず管理する保存先という役割を分けます。

このコードはキャッシュサービス自体の障害までは吸収しません。取得・保存がエラーになれば処理は止まるので、必要なら障害時に元の計算へ進むかを別に設計します。ローカルでは代用キャッシュのヒット、未存在、不正JSON、不正な型、再計算失敗を確認しました。Google上の保持時間は未計測です。処理の分離はGASコードの整理も参考になります。

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次