Job 類中 $timeout 設定無效 ? - 已關閉

beatles發表於2020-08-07

環境

linux + php7.4(pcntl enabled) + laravel7

問題背景

有如下兩個佇列任務:

  • JobA 是發郵件, 希望限定 timeout=60s(也就是預設 --queue=default --timeout=60)
  • JobB 是大檔案上傳, 耗時較長, 希望限定 timeout=3600s (1h)

期望的程式碼實現

// JobA
class JobA implements ShouldQueue
{
    ...
    $tries = 1;
    $timeout = 60;
    ...
    public function handle()
    {
        logger('JobA start at: ' . date('Y-m-d H:i:s'));
        sleep(70);
        logger('JobA end at: ' . date('Y-m-d H:i:s')); // exceed timeout, fail to log
    }
}
// JobB
class JobA implements ShouldQueue
{
    ...
    $tries = 1;
    $timeout = 120;
    ...
    public function handle()
    {
        logger('JobB start at: ' . date('Y-m-d H:i:s'));
        sleep(70);
        logger('JobB end at: ' . date('Y-m-d H:i:s')); // won't exceed timeout, success to log
    }
}
// terminal, 命令列不使用 --timeout 則預設 60
$ php artisan queue:work --timeout=60

// 分別呼叫
dispatch(new JobA); // 超時, jobA end 不能輸出
dispatch(new JobB); // 結果也是超時, JobB end 也不能輸出, 說明 JobB 中的 $timeout 設定無效

問題

按文件中寫的 job 類中的 $timeout 應該是要優先於命令列中的 --timeout 設定, 但現在結果並不是. [已解決, 見末尾]

另附繞過 Job 類中設定 $timeout 臨時解決辦法

命令列中的 –timeout 是有效的, 所以使用兩個程式兩個佇列倒是可以實現類似效果

// terminal, 命令列不使用 --timeout 則預設 60
$ php artisan queue:work --timeout=60 --queue=queueA
$ php artisan queue:work --timeout=120 --queue=queueB
// 分別呼叫
dispatch(new JobA)->onQueue('queueA'); // 超時, jobA end 不能輸出
dispatch(new JobB)->onQueue('queueB'); // 結果未超時, JobB end 能輸出, 說明命令列中 --timeout 設定可用

已解決, 原因是: 不僅要 pcntl enable, php.ini disable_functions 不能 disable 掉相關的函式.

另外, 要使用 queue:work 而不是 queue:listen 才能使 Job 類內的 $timeout 優先順序高於命令列的 –timeout 參考自github issue:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章