クマのブログ

つまづいたところ、学びを書いていきます

【Laravel8.0】キュー・ジョブの処理でのMaximum execution time of 60 seconds exceeded

前提

Windows 10

・Laravel 8.0

背景

Laravel実践開発を進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ

事象

P188でキューを非同期で対応させるために、書籍通り進めた。

具体的には

  1. キュー用テーブルの作成
php artisan queue:table
  1. マイグレーション
php artisan migrate
  1. 実行失敗時テーブル作成
php artisan queue:failed-table

の順で実行。

  1. については

A CreateFailedJobsTable class already exists.

というエラーが返ってきたので、マイグレーション不要、と判断。

そして、

「せっかくだしリセットしたい」

という少し謎な判断が働き、

php artisan megrate:fresh

を実行。

(ここで、改めてCreateFailedJobsTableが作成されていることを認識)

  1. .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なので、アクセス時にジョブが一時的にテーブルに保存されなければいけない。

↓これができていない… f:id:kuma_kuma0121:20210723231119p:plain

cacheによるエラー可能性②

再度、以下実行。

php artisan cache:clear

結果:変化なし。解決せず。

configによるエラー可能性②

では、configは?とダメもとで以下実行。

php artisan config:clear

結果:解決。databaseにジョブが保存されるようになった。 f:id:kuma_kuma0121:20210723231239p:plain

所感

・.envファイル、configフォルダ直下のファイルを触ったら残ったcacheやconfigを疑う、というスタンスの定着に1歩近づきました。

・laravel.logを確認することでcmd以上の詳細のエラー情報が確認できるため、必ず確認すべきと実感。

・何よりも最初の

Maximum execution time of 60 seconds exceeded

の要因が特定できなかったことは非常に悔しい点。

参考記事

Laravel実践開発