Laravel - Digging Deeper - Task Scheduling (官方文件原子化翻譯)

# Introduction

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。



# Defining Schedules

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Console;

    use Illuminate\Console\Scheduling\Schedule;
    use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
    use Illuminate\Support\Facades\DB;

    class Kernel extends ConsoleKernel
    {
    protected $commands = [
    //
    ];

    protected function schedule(Schedule $schedule)
    {
    $schedule->call(function () {
    DB::table('recent_users')->delete();
    })->daily();
    }
    }
  • Answer:
    App\Console\Kernel class 的 schedule method 中定義 schedule, 在每天的晚上 12 點刪除 records in recent_users table
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(new DeleteRecentUsers)->daily();
  • Answer:
    除了 schedule closure, 也可以 schedule invokable object
以下的 Laravel example command 的意思是?
  • Example:
    <?php
    php artisan schedule:list
  • Answer:
    列出所有已定義的 schedule overview

# Scheduling Artisan Commands

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use App\Console\Commands\SendEmailsCommand;

    $schedule->command('emails:send Taylor --force')->daily();

    $schedule->command(SendEmailsCommand::class, ['Taylor', '--force'])->daily();
  • Answer:
    使用 Laravel schedule 來 schedule command
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use App\Jobs\Heartbeat;

    $schedule->job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes();
  • Answer:
    使用 Laravel schedule 來 schedule job, 並指定 queue 以及 connection

# Scheduling Shell Commands

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->exec('node /home/forge/script.js')->daily();
  • Answer:
    使用 Laravel schedule 來 schedule shell command

# Schedule Frequency Options

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->cron('* * * * *');
  • Answer:
    客製化的 cron schedule
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyMinute();
  • Answer:
    每分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyTwoMinutes();
  • Answer:
    每 2 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyThreeMinutes();
  • Answer:
    每 3 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyFourMinutes();
  • Answer:
    每 4 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyFiveMinutes();
  • Answer:
    每 5 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyTenMinutes();
  • Answer:
    每 10 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyFifteenMinutes();
  • Answer:
    每 15 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyThirtyMinutes();
  • Answer:
    每 30 分鐘執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->hourly();
  • Answer:
    每 1 小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->hourlyAt(17);
  • Answer:
    每 1 小時的 17 分執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyTwoHours();
  • Answer:
    每 2 小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyThreeHours();
  • Answer:
    每 3 小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everyFourHours();
  • Answer:
    每 4 小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->everySixHours();
  • Answer:
    每 6 小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->daily();
  • Answer:
    每 1 天 00:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->dailyAt('13:00');
  • Answer:
    每 1 天的 13:00 時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->twiceDaily(1, 13);
  • Answer:
    每 1 天的 01:00 以及 13:00 時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->weekly();
  • Answer:
    每個 Sunday 00:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->weeklyOn(1, '8:00');
  • Answer:
    每個 Monday 8:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->monthly();
  • Answer:
    每個月的第一天 00:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->monthlyOn(4, '15:00');
  • Answer:
    每個月的第四天 15:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->twiceMonthly(1, 16, '13:00');
  • Answer:
    每個月的第一天, 第十六天 13:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->lastDayOfMonth('15:00');
  • Answer:
    每個月的最後一天, 15:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->quarterly();
  • Answer:
    每季的第一天 00:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->yearly();
  • Answer:
    每年的第一天 00:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->yearlyOn(6, 1, '17:00');
  • Answer:
    每年的六月一號 17:00 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->timezone('America/New_York');
  • Answer:
    定義 schedule timezone
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->weekly()->mondays()->at('13:00');

    $schedule->command('foo')
    ->weekdays()
    ->hourly()
    ->timezone('America/Chicago')
    ->between('8:00', '17:00');
  • Answer:
    除了直接使用 constraint method, 也可以將不同的 constraint 連接起來
    每個禮拜一的 13:00 執行
    星期 1 - 5, 8:00 到 17:00 每小時執行一次
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->weekdays();
  • Answer:
    禮拜 1 - 5 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->weekends();
  • Answer:
    禮拜六 - 日 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->sundays();
  • Answer:
    禮拜日執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->mondays();
  • Answer:
    禮拜一執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->tuesdays;
  • Answer:
    禮拜二執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->wednesdays;
  • Answer:
    禮拜三執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->thursdays;
  • Answer:
    禮拜四執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->fridays;
  • Answer:
    禮拜五執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->saturdays();
  • Answer:
    禮拜六執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->days(array|mixed);
  • Answer:
    在指定的 days 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->bewteen($startTime, $endTime);
  • Answer:
    在指定的時間區間內執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->unlessBetween($startTime, $endTime);
  • Answer:
    只在指定的時間區間內不執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->when(Closure);
  • Answer:
    當 closure return true 時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->call(function () {
    //
    })->enviroments($env);
  • Answer:
    若為指定的 env 時則執行, 例如 staging 或 production

# Day Constraints

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->hourly()
    ->days([0, 3]);
  • Answer:
    在禮拜日, 禮拜三的每小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Console\Scheduling\Schedule;

    $schedule->command('emails:send')
    ->hourly()
    ->days([Schedule::SUNDAY, Schedule::WEDNESDAY]);
  • Answer:
    在禮拜日, 禮拜三的每小時執行

# Between Time Constraints

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->hourly()
    ->between('7:00', '22:00');
  • Answer:
    在 7:00 到 22:00 之間, 每小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->hourly()
    ->unlessBetween('23:00', '4:00');
  • Answer:
    在 23:00 到 04:00 之間不執行, 其餘時間每小時執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')->daily()->when(function () {
    return true;
    });
  • Answer:
    每天的 00:00, 若 when() 內 closure return true 執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')->daily()->skip(function () {
    return true;
    });
  • Answer:
    每天的 00:00, 若 skip() 內 closure return true 則不執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->environments(['staging', 'production']);
  • Answer:
    每天的 00:00, 若 env 為 staging 或 production 時執行

# Timezones

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('report:generate')
    ->timezone('America/New_York')
    ->at('2:00')
  • Answer:
    New_York 時間的 2:00 執行
以下位於 App\Console\Kernel 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected function scheduleTimezone()
    {
    return 'America/Chicago';
    }
  • Answer:
    在 App\Console\Kernel 的 scheduleTimezone() 內可定義適用於 schedule 的 global timezone
Laravel 中, 為何不建議 timezone scheduling?

因為一些時區會使用夏令制, 也就是可能會多一個小時或少一個小時, 這會造成一個 schedule 在一天內執行兩次, 或完全不執行


# Preventing Task Overlaps

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')->withoutOverlapping();
  • Answer:
    使用 withoutOverlapping() 來避免 task 已經在執行中了, 又被執行
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')->withoutOverlapping(10);
  • Answer:
    使用 withoutOverlapping() 來避免 task 已經在執行中了, 又被執行, 預設 withoutOverlapping lock 會在 24 hours 後失效, 也可帶入時間自定義, 單位為 minute

# Running Tasks On One Server

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('report:generate')
    ->fridays()
    ->at('17:00')
    ->onOneServer();
  • Answer:
    如果是跑多台 server 的話, scheduled task 很有可能會在多台 server 同時執行, 這樣就執行了多次, 浪費效能, 可使用 onOneServer(), 第一台取得該 scheduled task 執行權的 server 會給該 task 加上一個 lock, 避免重複執行

# Background Tasks

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('analytics:report')
    ->daily()
    ->runInBackground();
  • Answer:
    當使用 scheduled task 時, 預設會按照順序執行的, 如此一來, 如果遇到耗時較久的 task, 很有可能會造成阻塞, 這時可使用 runInBackground() 讓不同的 task 同時被執行, runInBackground() 只適用於 command 或 exec 的 scheduled task

# Maintenance Mode

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')->evenInMaintenanceMode();
  • Answer:
    預設在 maintenance mode 時, scheduled task 是不會被執行的, 如果依然想要執行的話, 可使用 evenInMaintenanceMode()

# Running The Scheduler

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
  • Answer:
    schedule:run 指定會去判斷當下時間是否有需要執行任何已定義的 scheduled task, 所以必須使用 cron server, 每分鐘都執行一次 schedule:run

# Running The Scheduler Locally

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    php artisan schedule:work
  • Answer:
    在本地開發時, 我們不太會使用 cron 來跑 scheduled task, 這時可使用 schedule:work command 來暫時跑一個 process 在 foreground, 每分鐘都去執行 schedule:run

# Task Output

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->sendOutputTo($filePath);
  • Answer:
    定義 scheduled task 的 output 位置, 會覆蓋該檔案
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->appendOutputTo($filePath);
  • Answer:
    定義 scheduled task 的 output append 位置, append 輸出
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('report:generate')
    ->daily()
    ->sendOutputTo($filePath)
    ->emailOutputTo('taylor@example.com');
  • Answer:
    定義 scheduled task 的 output 位置, 可定義機器內的檔案位置, 或是將 output 透過 email 發送
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('report:generate')
    ->daily()
    ->emailOutputOnFailure('taylor@example.com');
  • Answer:
    定義 scheduled task 的 output 透過 email 方式發送, 且只有在 non-zero exit code 時才發送

# Task Hooks

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->before(function () {
    // do something
    })
    ->after(function () {
    // do something
    });
  • Answer:
    使用 before(), after(), 在 scheduled task 被執行前以及執行後執行一些邏輯
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    use Illuminate\Support\Stringable;

    $schedule->command('emails:send')
    ->daily()
    ->onSuccess(function (Stringable $output) {
    // do something
    })
    ->onFailure(function (Stringable $output) {
    // do something
    });
  • Answer:
    使用 onSuccess(), onFailure(), 在 scheduled task 執行成功或失敗後做一些事, 並且可使用 type hint Stringable 來存取 output

# Pinging URLs

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->pingBefore($url)
    ->thenPing($url);
  • Answer:
    使用 pingBefore(), thenPing(), 在 scheduled task 執行前後 ping 指定的 url
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->pingBeforeIf($condition, $url)
    ->thenPingIf($condition, $url);
  • Answer:
    ping arg2 的 $url, 如果 arg1 $condition 為 true 的話
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->daily()
    ->pingOnSuccess($successUrl)
    ->pingOnFailure($failureUrl);
  • Answer:
    會在 success 時 ping $successUrl, fails 時 ping $failureUrl
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $schedule->command('emails:send')
    ->twiceDailyAt(1, 13, 5);
  • Answer:
    一天跑兩次, 分別在 01:05, 以及 13:05 時執行
Laravel - Eloquent ORM - Serialization (官方文件原子化翻譯) Laravel - Digging Deeper - Mail (官方文件原子化翻譯筆記)

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×