Skip to content

キャッシュシステム v0.3.0~

babyrite は並行キャッシュライブラリ moka を使用し,Discord API で取得できたチャンネル情報をキャッシュし,再取得の手間を短縮しています.

キャッシュシステムの技術的制約について

  • チャンネルの作成・更新・削除 (スレッドを含む) を Discord から受け取った時点で,該当チャンネルとそのギルドのキャッシュを破棄します.
    • チャンネルを非公開にした場合,その変更は即座に反映されます.
    • ただしゲートウェイの再接続でイベントを取りこぼした場合は反映されません.この場合も TTL により 1 時間以内に解消します.
  • キャッシュのキーはプロセス全体で共有します.
    • GUILD_CHANNEL_CACHE のキーは channel_id のみであり,別のギルドのために取得したチャンネルもヒットし得ます.
    • そのため取得時に,そのチャンネルが要求したギルドのものであるかを検証します.一致しない場合はチャンネルを返さずエラーにします.

対応している機能

GitHub Permalink は対応していません.毎回 raw.githubusercontent.com に直接取得しています.

キャッシュ構成

babyrite はマシン上のメモリに以下のキャッシュ構成を組みます.

キャッシュキー→値用途
GUILD_CHANNEL_LIST_CACHEGuildIdHashMap<ChannelId, GuildChannel>ギルド単位のチャンネル一覧
GUILD_CHANNEL_CACHEChannelIdGuildChannel個別チャンネル

両方とも以下のような共通設定で動作します:

  • 最大 500 エントリ
    • Least Recently Used (LRU) に基づいてキャッシュを整理します.
    • サイズ超過分は最近最も使われなかったデータから削除します.
  • TTI (Time To Idle):
    • 1 時間アクセスがないデータを自動的に削除します.
  • TTL (Time To Live):
    • アクセス頻度に関わらずデータは 1 時間で失効します.
    • キャッシュされたチャンネル情報は権限の判定に使われるため,TTL は単なるメモリ上限ではなく,取りこぼしたイベントの影響が残る上限でもあります.

キャッシュのルックアップ手順について

メッセージ引用

  1. GUILD_CHANNEL_CACHE (チャンネルキャッシュの集合体) からキャッシュを検索します
    • ヒットした場合,そのチャンネルが要求したギルドのものであれば返します.
    • 別のギルドのチャンネルだった場合はエラーにします.(チャンネル ID は Discord 全体で一意なので,これは要求自体が誤っていることを意味します)
  2. 取得できなかった場合は GUILD_CHANNEL_LIST_CACHE (チャンネルリストキャッシュの集合体) を引く
    • ヒットすればそのマップから対象チャンネルを探します.
    • ヒットしなかった場合は Discord API から取得するようにし,結果をキャッシュに格納します.
  3. チャンネル一覧に対象のチャンネルが見つからない場合,アクティブスレッドを検索します.(スレッドはチャンネルリストには含まれないため)
  4. 見つかったチャンネルは最終的にキャッシュにも書き込まれます.