前提
・Windows 10
・Laravel 8.0
背景
Laravel実践開発を進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ
事象
P188でキューを非同期で対応させるために、書籍通り進めた。
具体的には
- キュー用テーブルの作成
php artisan queue:table
php artisan migrate
- 実行失敗時テーブル作成
php artisan queue:failed-table
の順で実行。
- については
A CreateFailedJobsTable class already exists.
というエラーが返ってきたので、マイグレーション不要、と判断。
そして、
「せっかくだしリセットしたい」
という少し謎な判断が働き、
php artisan megrate:fresh
を実行。
(ここで、改めてCreateFailedJobsTableが作成されていることを認識)
- .envファイルの修正
以下のように修正
QUEUE_CONNECTION = sync ↓ QUEUE_CONNECTION = database // sync→databaseへ変更 QUEUE_DRIVER = database // 項目ごと追記
5,. ワーカー実行 サーバーを起動しているcmd以外にもう1個cmdを起動し、
php artisan queue:work
を起動
実際のソースコードは以下の通り。
(中略) public function index(Person $person = null) { if ($person != null) { MyJob::dispatch($person)->delay(now()->AddMinutes(1)); } $msg = 'show people record.'; $result = Person::get(); $data = [ 'input' => '', 'msg' => $msg, 'data' => $result, ]; return view('hello.index', $data); }
use App\Person; 追加 (中略) class MyJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $person; public function __construct(Person $person) { $this->person = $person; } public function handle() { $sufix = ' [+MYJOB]'; if (strpos($this->person->name, $sufix)) { $this->person->name = str_replace( $sufix, '', $this->person->name); } else { $this->person->name .= $sufix; } $this->person->save(); } }
エラー発生
これで、指定されたURLにアクセスすればHelloController.phpの
MyJob::dispatch($person)->delay(now()->AddMinutes(1));
のジョブが1分後に実行される。
実際にアクセスすると
Maximum execution time of 60 seconds exceeded
というエラーが発生。
また、今まで正常にアクセスできたルートまでもアクセスできなくなり、途方に暮れる。
試したこと
一旦元の状態に戻す
一旦態勢を整えるべく.envファイルの設定を元に戻して正常状態に戻そうとした。
QUEUE_CONNECTION = database ↓ QUEUE_CONNECTION = sync // database→syncへ変更 QUEUE_DRIVER = database // 項目ごと削除
結果:変化なし。解決せず。
エラー原因特定
元に戻せないのはおかしいと思い、次にエラーのあたりを付けるため、storage/logs/laravel.logにてエラーログを確認
local.ERROR: Maximum execution time of 60 seconds exceeded {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Maximum execution time of 60 seconds exceeded at C:~\\~\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:685)
先ほど、QUEUE_CONNECTION = syncに直したにも関わらず、Databaseへアクセスしようとしている。 これが原因?
cacheによるエラー可能性
.envファイルを変更したため、変更前情報がcacheに保存されており、その情報を自動的に拾ってきていないか確認するため、以下実行。
php artisan cache:clear
結果:変化なし。解決せず。
configによるエラー可能性
では、configは?とダメもとで以下実行。
php artisan config:clear
結果:変化なし。解決せず。
PCをシャットダウン・再起動
ここで集中が切れて、次の日へ持ち越し。
一旦、再起動し、シャットダウン実行。
再度、参考書の通りに実装
次の日に手順の最初から実装し直し。
結果:エラーが出なくなった。
一旦は安心。(ただ、根本的な原因がわからずじまい)
ただ、ここで別の問題が。
ジョブの保存先がdatabaseなので、アクセス時にジョブが一時的にテーブルに保存されなければいけない。
↓これができていない…
cacheによるエラー可能性②
再度、以下実行。
php artisan cache:clear
結果:変化なし。解決せず。
configによるエラー可能性②
では、configは?とダメもとで以下実行。
php artisan config:clear
結果:解決。databaseにジョブが保存されるようになった。
所感
・.envファイル、configフォルダ直下のファイルを触ったら残ったcacheやconfigを疑う、というスタンスの定着に1歩近づきました。
・laravel.logを確認することでcmd以上の詳細のエラー情報が確認できるため、必ず確認すべきと実感。
・何よりも最初の
Maximum execution time of 60 seconds exceeded
の要因が特定できなかったことは非常に悔しい点。