はじめに
Laravelでタスクスケジューラーが必要になった時、セオリーとしてはKernel.phpにscheduleメソッドをつらつらと書き、cronから毎分artisanコマンド schedule:run
をコールするよう設定するはずだ。そして、それで十分というプロジェクトも多いだろう。
Laravel 6.x タスクスケジュール
しかしある程度タスクが増え、実行結果確認が毎度必要で、場合によっては再実行が求められるプロジェクトでは、このやり方では甚だ不十分である。ではどうするか?
その答えのひとつが、今回紹介する codestudiohq/laravel-totem である。
laravel-totemが提供するもの
まず大前提として、laravel-totemはGUIで各種操作を提供している。GUIには、ブラウザから /totem
というディレクトリに移動することでアクセスできる。
美しいGUI
百聞は一見にしかず。以下はタスク一覧。他の画面を見たい人はコチラ。
認証
web上に公開されている画面となるため、認証は必須である。ただしlaravel-totemが提供するのは認証の一部分のみである。どういうことかは以下のコードを見てもらえばおわかりいただけるだろう。要は既存の認証機能を使い、結果だけをlaravel-totemに連携せよということである。
public function boot()
{
Totem::auth(function($request) {
// return true / false . For e.g.
return Auth::check();
});
}
あるいは、特定のIPアドレスからのみアクセスを許可するといったケースにも簡単に対応できる。
use Symfony\Component\HttpFoundation\IpUtils;
public function boot()
{
Totem::auth(function($request) {
// return true / false . For e.g.
return IpUtils::checkIp($request->ip(), ['192.168.1.0/24', '192.168.1.15/32']) ? true : false;
});
}
細やかなスケジュール設定
scheduleメソッドでは時間以外の細やかな設定ができるが、それとほぼ同等の設定がGUIでできる。時間はもとより、メンテナンスモード中も実行できるか、多重実行できるか、といったオプションを気軽に指定できるのがありがたい。
手動実行
画面上のアイコンから、手動実行ができる。例えばスケジュール通りに動くべきタスクがエラーでこけていた際の再実行などで役立つはずだ。ただし、後述の留意点にある通りmax_execution_time
に注意すること。
実行結果の記録
実行ログおよび、終了時間、処理秒数を記録する。これにより、例えば日々のパフォーマンスを確認してタスクのパフォーマンス改善の要不要を判断できるようになる。なお記録は希望日数分残すことができる。
実行通知
メール通知は言うに及ばずslack通知が簡単にできるのがありがたい。slackのwebhook URLを登録するだけでできる。ただ通知は非常に簡素なのので、若干物足りなさは感じるかもしれない。
導入の難易度
github上の説明を元に実施すれば、躓くことは無かった。ただし、config/totem.php
を作りたい場合の手順は記載されていないので、以下のコマンドで実行する。
php artisan vendor:publish --tag=totem-config
留意点
実際使ってみたときに気づいた留意点は以下の通りである。
実行ログに記録される時間はDBのタイムゾーン依存
CURRENT_TIMESTAMPで日時を登録しているため、アプリはJST、DBのタイムゾーンがUTCというケースでは、実行ログの時間が実際の実行時間とズレているように見える。
スケジュール実行はあくまでcron依存
laravel-totemでスケジュールを設定したとしても、cronから schedule:run
コマンドを毎分実行しないと、スケジュール通りに動いてくれない。例えばdockerなどのローカル環境で開発しているときには、スケジュール通り動作するかの検証は難しいかもしれない。
手動実行はmax_execution_timeの制約下
cronからキックするのではなく、laravel-totemから手動でタスクをキックする場合、php.iniのmax_execution_time
の制約を受ける。つまりその値が30秒ということであれば、実行完了まで30秒を超えるタスクは、Maximum execution time of 30 seconds exceeded
というメッセージとともにFatal Errorとなる。よってタスク実行専用のサーバーにてtotemを運用する場合は、思い切ってphp.iniの当該パラメータの値に余裕を持たせておくことが望ましい。一方通常のAppサーバーにてtotemを運用する場合は、各プログラム内で set_time_limit(120);
というように都度制限時間を変更することが望ましい。
テーブル名の衝突に注意
totemでは、スケジュール管理、結果保存のためにDBに専用テーブルをいくつか作成する。その中には Tasks
などといういかにも衝突しそうな名前のテーブルが存在するため、.env
にTOTEM_TABLE_PREFIX
というパラメータを追加の上、totem_
などのプレフィックスを設定しておくほうが良い。
テーブル設定のキャッシュ問題
どういうタイミングで起きるかは不明であるが、すでにtotem用のテーブルを作成した後何らかの理由でこれらを削除して作り直そうとすると、以下のようなエラーが発生する。
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'homestead.fuga_task_frequencies' doesn't exist
これは、totemが下記のようにCacheにテーブル情報を格納した結果発生している。
https://github.com/codestudiohq/laravel-totem/blob/2d09bd8c9dd28aa04cfe037298323bf4718bb967/src/Totem.php#L94
したがってCashe先のデータを削除する必要がある。redisの場合はkeys *totem*
で関連するキャッシュが見つかるので、それらを指定して削除すれば良い。