はじめに
Github Actions
でcron
を用いて、データの自動削除機能を作成する必要がありました。
cronやバッチ処理自体作成したことがなかったので、どのように実装したかをまとめます。
cronとは
ccronは、定期的にコマンドを実行するための仕組みです。
バックグラウンドで動作する「デーモン」として、指定したスケジュールに従って処理を実行します。
では、デーモンとは何か
コンピュータシステムにおいてバックグラウンドで常時動作し、特定のタスクやサービスを提供するプログラムのこと
これらの内容は、以下の記事を参考にしました
課題
以下の要件で実装しました。
-
Supabase
に登録されているユーザー情報を、毎日一定の時間に削除する - 削除対象は、前日に登録されたユーザー情報とする
実装したこと
GitHub Actionsのワークフロー設定
name: schedule delete user
on:
schedule:
- cron: '0 21 * * *' # UTCで21時(JST朝6時)に実行
workflow_dispatch: # 手動実行も可能
jobs:
delete-users:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run batch to delete users
run: npx tsx ./batch/index.ts
env:
VITE_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
VITE_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
バッチ処理の作成
// 24時間以上前に登録されたユーザーデータを削除するバッチ
async function cleanupOldUserData() {
try {
// 現在時刻から24時間前を計算
const dayAgo = new Date();
dayAgo.setHours(dayAgo.getHours() - 24);
// 削除処理実行
const result = await deleteUsersCreatedBefore(dayAgo);
if (result) {
console.log('ユーザーデータの削除に成功しました');
} else {
throw new Error('ユーザーデータの削除に失敗しました');
}
} catch (error) {
console.error('バッチ処理でエラーが発生しました:', error);
process.exit(1); // エラー終了
}
}
苦労したポイント
cronの設定
日本時間の朝6時にバッチを実行したかったのですが、GitHub ActionsはUTC基準で動作します。
そのため、UTCの21時(JST朝6時)に設定する必要がありました。
cron: '0 21 * * *' # UTCの21時 = JSTの午前6時
時差対応
① JavaScriptのDate
はUTC基準で内部管理されているが、表示は実行環境のタイムゾーンに依存
② Supabase
のデータベースは、PostgreSQLのタイムスタンプはUTC基準で保存
③ GitHub Actions
は実行環境もUTC基準
上記のことを踏まえて、整理すると
① ではGitHub Actionsで実行されるときは、UTC基準で日時が取得されるので、UTC基準の24時間前の時間をセット
const dayAgo = new Date();
dayAgo.setHours(dayAgo.getHours() - 24);
② では、常にUTC基準なので SQL で Supabaseのテーブルに保存されている登録時のタイムスタンプと比較することが可能
export async function deleteUsersCreatedBefore(
beforeTime: Date
): Promise<boolean> {
try {
...
.lt('created_at', beforeTime);
これらの対応をとることにより、UTC基準での24時間前より前に作成されたレコードを定期的に削除する、バッチ処理を実装することができました!
まとめ
今回は、時間帯による挙動の違いを理解して、バッチの実行時間やデータ処理の範囲を適切に設計することの重要性を学ぶことができました。