Laravel - Task Scheduling

Makale İçerik Listesi

Basit Schedule Oluşturmak

  1. Task Schedule'lar app/Console/Kernel.php dosyasındaki schedule metodunda belirtilir.
  2. İlk olarak direk schedule metodunun içinde bir closure olarak task schedule yazacak olursak, şu şekilde olur 
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            DB::table('recent_users')->delete();
        })->daily();
    }
  3. schedule:list artisan komutu bir sonraki scheduled taskler neler onu gösterir. 
    php artisan schedule:list

Command Oluşturmak

  1. Artisan commandleri ile de schedule oluşturabiliriz.
  2. Artisan ile yapılabilecekleri php artisan list ile görebiliriz.
  3. Artisan ile yapabileceğimiz şeylerden biri de php artisan make:command örnek olarak 
    php artisan make:command DailyMessage

    bunu yazdıktan sonra app/Console/Commands içinde DailyMessage.php diye bir command dosyası oluşur.

  4. Buradaki $signature'a düzgün isim vermek çok önemli. Neticede console'dan bu isimle çağrılacak. O nedenle anlamlı bir isimle değiştiriyorum. 
    protected $signature = "message:daily";

    hatta derscription'ı da düzeltsek terminalde php artisan list dediğimiz zaman message sekmesinde daily commandini görebiliriz.

  5. Command'in birşey yapmasi için Command dosyasındaki handle() fonksiyonunda bir iş yapmamız lazım. Buraya basitçe birşey yazalım. 
    public function handle()
    {
        echo 'This is my first basic scheduler';
    }

    bunu yazdıktan sonra Terminal'de php artisan message:daily dediğimizde tek seferlik bu komut çalışır ve mesajımızı terminale basar.

  6. Ama bizim asıl istediğimiz bu komutun belli bir takvim(schedule) içerisinde otomatik olarak çalıştırılması.

Command ile Schedule Oluşturmak

  1. app/Console/Kernel.php dosyası içindeki schedule() metoduna Closure yerine oluşturduğumuz command'i de verebiliriz. 
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('message:daily')->hourly();
    }
  2. Timeinterval'ler konusundaki opsiyonlarımızı görmek için https://laravel.com/docs/8.x/scheduling#schedule-frequency-options buraya bakabiliriz.
  3. Scheduler yaptığı işin çıktısını nereye dökeceğini kendi kendine bilemez. Onun için bir log dosyası belirliyorum. 
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('message:daily')
            ->everyMinute()
            ->appendOutputTo('scheduler.log');
    }
  4. İşlemlerin art arda birbiri üstüne binmeden yapılmasını istiyorsak withoutOverlapping() metodunu kullanabiliriz. 
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('emails:send')
            ->daily()
            ->withoutOverlapping();
    }
  5. Bundan sonra scheduler'ın lokalde çalışması için yapmamız gereken terminalde php artisan schedule:work komutunu çalıştırmak.

Schedule'ı Server'da Çalıştırma

  1. Bütün schedule işlemlerinin server'da çalışabilmesi için tek sefere mahsus bir CRON job çalıştırmamız lazım.
  2. Bu CRON job'un hiçbir output'u yok. Yaptığı tek şey schedule:run komutunu her dakika çalıştırmak.
  3. Her site için tek sefer yapacağımız bu işlem için Forge'da Server'ıma giriyorum.
  4. Scheduler tab'inde New Scheduled Job diyorum ve komut satırına 
    cd /home/forge/name-of-site-directory(example.com) && php artisan schedule:run >> /dev/null 2>&1
  5. User user
  6. Frequency -> Every Minute diyorum ve oluşturuyorum.
  7. Böylece artık sitenin kendi kaynak kodunda yapacağım her türlü schedule işlemi planlandığı gibi yapılacak.

Referanslar

  1. Laravel Docs - Task Scheduling - link
  2. Scheduler in Laravel 8 Youtube Video - link
  3. Laracasts - Intermediate Laravel: Scheduling Commands and Tasks - link