Laravel Queue ( Kuyruk ) Yapısı

Merhaba, 
bu yazıda Laravel ile küçük bir queue uygulaması örneğine değineceğim. Belki başkalarına bir faydası olur, en kötü ileride dönüp bakmak ve mantığını hatırlamak için güzel bir günlük olur diye düşündüm. 

Şimdi, bilinen ve en çok verilen örnek üzerinden gidelim ki daha rahat anlayalım. 

Diyelim ki sisteminizde kullanıcı bir tuşa bastı ve belirle işlemler yapıldı ve o kullanıcıya e-posta atılması gerekiyor. 

Ya da dokümantasyondaki örnekten gidelim. Bir csv dosyası üzerinde çeşitli işlemler yapacaksınız. İlgili sayfaya tıkladığınızda tahmin edeceğiniz üzere epeyce beklemeniz gerekiyor. ( En azından bir süre )

Bir diğer örnek de şu olabilir. Sisteminizde birkaç işlem yaptınız ve kayıtlı olan tüm kullanıcılara e-posta atılması gerekiyor. Diyelim ki yüzlerce hatta binlerce kullanıcınız var. Siz butona tıkladığınızda çok uzun süreler beklemek zorunda kalmak istemezsiniz değil mi? Sonuçta başka işleriniz de var sistem üzerinde yapmanız gereken. 

İşte tam burada Queue kavramı devreye giriyor. 

Burada yapmanız gereken, bir adet queued job oluşturmak. Siz diğer işlemlerinize devam ederken  mail atma işlemi arka planda devam edecektir. 

Konfigürasyon işlemleri için config/queue.php dosyasına bakabilirsiniz. 

Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"

Yukarıda görüldüğü gibi birçok konuda desteğimiz var. Eş zamanlı yapmak isteyebiliriz ( ki bu durumda epeyce beklememiz gerekecek ), database üzerinden yapabiliriz, Amazon SQS ya da redis kullanabiliriz. Seçimi bize kalmış.

Biz kendi içimizde halletmek istediğimiz için database ile devam edeceğiz.

Evet, o zaman başlayalım. 

Öncelikle yapmanız gereken ilk şey, .env dosyası içinde bulunan 

QUEUE_CONNECTION=sync

ifadesini

QUEUE_CONNECTION=database

olarak değiştirmek olacaktır. 

Ardından yine .env dosyası içinde bulunan mail ile ilgili olan kısımları doldurun. Ben mailtrap kullandım test için. Siz kullanıcı adı ve şifre ksımlarını doldurmayı unutmayın. 

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME="${APP_NAME}"

 

Sonra, aşağıdaki komutları çalıştırın. 

php artisan queue:table

php artisan migrate

Database içine bakarsanız, jobs adında bir tablo oluştuğunu göreceksiniz.

Unutmadan hemen bir job oluşturalım. Aşağıdaki komutu kullanabilirsiniz. Ben adına SendMailJob dedim. Siz ihtiyacınız göre isimlendirebilirsiniz.

php artisan make:job SendMailJob

Dikkat ederseniz, app altında jobs adında bir klasör oluşturdu ve içine de SendMailJob.php adında bir dosya oluşturdu.

İçerisini şu şekilde değiştirdim. 

protected  $user;
protected  $aciklama;

  public function __construct( User $user, $aciklama = "")
  {
      $this->user = $user;
      $this->aciklama = $aciklama;
  }


  public function handle()
  {
      $user = $this->user;
      $aciklama = $this->aciklama;

      Mail::to($user->email)->send(new SendMail($user, $aciklama));

  }

Yukarıdaki kod bize şunu anlatıyor. 2 adet değişken alıyoruz. $user değişkenini modelden alıyoruz, eğer bir açıklama girdiysek o açıklamayı da belirtiyoruz. 

handle() metodu içinde de az sonra oluşturacağımız SendMail dosyamızdan bir örnek oluşturup mail işlemini gerçekleştiriyoruz.

 

Biz, kendi senaryomuzda mail gönderme işlemi yapacağımız için hemen bir de mail oluşturalım. Ben anlaşılır olsun diye adını SendMail koydum.  Kullanıcı bir işlem yaptığında kendisine mail atılacak. 

php artisan make:mail SendMail

Dikkat ederseniz, app altında Mail adında bir klasör oluşturdu ve içine de SendMail.php dosyasını attı. 

İçerisini şu şekilde düzenledim.

public $user;
public $yazi;

public function __construct($user, $yazi )
{
   $this->user = $user;
   $this->yazi = $yazi;
}

public function build()
{

   $user = $this->user;
   $yazi = $this->yazi;

   return $this->view('mail')->with([
          'user' => $user,
          'yazi' => $yazi
   ]);
}

SendMail.php dosyasında işlemin yapıldığı kısım build() metodu. Bir tane mail.blade.php dosyası oluşturalım ve basitçe şu şekilde yapalım. 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>E-Mail Test</title>
    
</head>
<body>

    <div class="container">

        <div class="row">
            <div class="col-md-12">
                <p class="text-center">
                   
                    <!-- SendMail.php dosyasından gelen user -->
                    Merhaba sayın {{ $user->name }},

                </p>
            </div>

            <div class="col-md-12">

                <p style = "background: #333; color: #fff; padding: 10px">
                    
                    <!-- SendMail.php dosyasından gelen yazi -->
                    {{ $yazi }}

                </p>

                <p style = " padding: 10px">
                   Giriş yapmak için 
                  <a style = "color: orangered;" href="https://www.ufukucar.com">Tıklayınız..</a>
                </p>

            </div>

        </div>


    </div>

</body>
</html>

 

Son olarak, yeni bir terminal ekranında proje dizinimizin olduğu yere gelelim. 

Aşağıdaki kodu çalıştıralım. Artık önemli olan konular başlıyor. Lütfen dikkat edelim. 

php artisan queue:work

Şimdi gelelim asıl işimize, xxx.com/test adında bir adresimiz olsun. 

web.php dosyasında şu şekilde karşılayalım. 

Route::get('/test', function () {

    $user = \App\Models\User::find(1)->first();

    dispatch(new \App\Jobs\SendMailJob($user,  "Sitemize hoşgeldiniz! "));

    return 'E-posta gönderildi';

})->name('test');

 

Yukarıdaki basit kodu hemen açıklayalım. 

1 numaralı id ye sahip kullanıcıyı bulup kendisine mail atıyoruz. 

İşimizi gören kısım aşağıda. Yeni bir SendMailJob örneği oluşturuyoruz ve constructorının içine hem $user ı hem de istediğimiz text içeriğiniz giriyoruz.

dispatch(new \App\Jobs\SendMailJob($user,  "Sitemize hoşgeldiniz! "));

Eğer belirli bir gecikmeden sonra yapılsın istiyorsak şu şekilde düzenlenebilir. Aşağıdaki kod ile 5 saniye sonra diyoruz.

dispatch(new \App\Jobs\SendMailJob($user, "Sitemize hoşgeldiniz!"))->delay(\Carbon\Carbon::now()->addSeconds(5));

 

Tarayıcınızdan xxx.com/test ya da localden localhost:8000/test adresinize girerseniz mail adresinize şuna benzer bir gelecektir. 

Evet, hepsi bu kadar..

 

 

 

 

202 Görüntülenme

Yorum Yap