Laravel Türkiye Discord Kanalı Forumda kod paylaşılırken dikkat edilmesi gerekenler!Birlikte proje geliştirmek ister misiniz?

CodeWriteson Sunucuda normal cron kullanmanız gerekiyor, bu komut sadece geliştirme ortamı için.

    mgsmus Hocam sizi bulmusken bir sorum vardi)) Queue jobs kullanim alani olarak en cok hangi islemlerde yaygin kullanilir yani ne zaman burda queue jobs kullanmam lazim denir.

      CodeWriteson Bir istekte yaptığınız işlemler bir sonrakini bloke edecek şekilde çalışır, yani tamamlanmadan diğer işleme geçmez. Bu işlemlerden bazıları aynı istekte olmak zorunda değildir, örneğin mail gönderme gibi. Bir sipariş kaydı oluşturunca sonrasında kullanıcı mail gitsin diye beklemek zorunda değil çünkü "siparişiniz alındı" maili siparişin oluşması için bir gereksinim değil. Bunu arka planda gönderebilirsiniz ve böylece kullanıcı deneyimi daha yumuşak olur.

      Bazı işlemler uzun sürebilir örneğin kayıtların Excel'e aktarılması, yıllık raporların oluşturulması ya da video render edilmesi gibi. Bu işlemler de arka planda yaptırılabilir. Kullanıcı sadece işlemi başlatır, bittiğinde dosyayı mail ile göndereceğiz gibi bir mesajla bilgilendirilir, uygulamayı kullanmaya devam eder. İşlem arka planda çalışır, kullanıcıyı bekletmez.

      Günlük rutin, periyodik işler arka planda yaptırılabilir. 3. parti servislerden bilgi çekmek, güncellemek, sistem taraması yapmak vs gibi. Bunlar cron ile yapılıyor fakat bazen istek sınırlamaları oluyor. Mesela elinizdeki kayıtları karşı tarafa iletip bazı verileri alacaksınız ya da elinizdekileri güncelleyeceksiniz. Tek seferde 100 tane yapabiliyorsunuz, limit var, ama sizde 1000 kayıt var. Cron ile çalışan zamanlanmış görev kayıtlardan 100'er tane çekip (chunk kullanarak mesela) güncellemeyi yapan bir Job'ı bu 100 kayıtla kuyruğa atar, toplamda 10 tane Job (1000 / 100 = 10) kuyrukta sıraya girer, hepsi sırayla çalışır. Bu şekilde limit problemlerini çözmenizi sağlayabilir.

      Bazen bazı işlemleri paralel gerçekleştirmek istersiniz, bu size zamandan tasarruf sağlar, bunun için birden fazla kuyruk kullanabilirsiniz. Örneğin 1000 kaydı işlemek 1000 dk sürüyorsa bunları 100'erli gruplar halinde aynı anda 10 farklı kuyruğa attığınızda 100 dk sürer.

      Bazı işlemler ilk seferinde başarılı olmaz, örneğin kullandığınız 3. parti servise anlık erişemeyebilirsiniz. Kuyruğa atılan işler tekrarlanabilir olduğu için bu tür işleri kuyrukta halletmek bu sorunu ortadan kaldırır. Örneğin iş, 3. denemesinde başarılı olur.

      Başka kullanım alanları da vardır ama genellikle hep benzer noktalarda buluşuyorlar o yüzden genel olarak bunlar.

        mgsmus Ancak bu kadar guzel anlatila bilirdi elinize saglik. O zaman soyle soyleleyim size gecen sefer anlattigim siteden veri cekme mesela. Benden 1000 sayfadan veri cekmem isteniyor. pagination var. O zaman Her page icin job yaratmam ve onu kuyrukla arka planda calistirmam gerek oyle degilmi? kullanicidida arkadan giden isdden haberi olmaz. Ve Crona bagli her 1 saatda bir request aticak , o zaman fazla bilgi icin job olusturucam oylemi? SAdece tek anlamadigm job un bir tanesi 1 sayfadan veri cekicekse diger joblari mesele 100 tane job lazim kuyrukta ayni isi gorucek dinamik olarak create yapmak mumkunmu? kendisi mesele 10000 veriyi 100 job olarak queue da isletsin.

          CodeWriteson

          $lastPage = 120; // Bunu önce çekeceksiniz. Çektiniz, 120 geldi.
          
          for($i = 0; $i < $lastPage; $i++) {
              ScrapUrl::dispatch(
                  sprintf("https://www.site.com/haberler?page=%d", $i)
              );
          }

          Bu yani kabaca yapacağınız.

          Daha önce de dediğim gibi sayfa no olmayan, arkada yapan, ajax kullanan vs siteler için strateji belirleyip nasıl sayfaladığını kayıtları getirdiğini bulup ona göre işlem yapacaksınız.

          Eyvallah. o zaman ben en iyisi scrapper manager i sizin onerdiginiz ScrapperMAnager - command icinde degilde job olusturarak onun icinde cagirayim .dogru anladim umarim. Bundan once ScrapperCommand olsuturmustum

          public function handle()
          {
          $scrapper = new ScrapperManager([
          Service1::class => 'url1l',
          Service2::class => 'url2r',
          ]);

              foreach($scrapper->scrap() as $data) {
                  // data --> ScrappedData olacaq.
                  News::firstOrCreate([
                      'site_name' => $data->getSiteName(),
                      'title' => $data->getTitle(),
                  ], [
                      'link' => $data->getLink(),
                      'img' => $data->getImage()
                  ]);
              }
          
              $this->info('Successfully scrapped');
          }

          sondada schedule:work yaparak calistiriyordum . commandi job a degistirecem o zaman oylemi?

            CodeWriteson Command kalacak, datayı çeken kısmı Job yapacaksınız. Komutu işleri kuyruğa atmak için kullanacaksınız. Yani ScrapperCommand her bir link için kuyruğa Job atmakla yükümlü olacak.

              mgsmus Hocam o zaman commandda yaptigim data cekmeyi job a aktaricam. Amma mesela her service de kendi icerisinda buyuk veriler return yapiyor. Ve en onda scrapper manager ile verilen toplaniyor bir yerde. O kisim icin job falan gerekli degilmi mesela her service icin. Sonucta veriler servislerden gelip toplaniyor ayni veri zaten toplaniyor ve en sonda isleniyor. Sadece command kisimdaki veri islemeyi job yaparsak yetecekmi?

              mgsmus Hocam birde son olarak queue_connection sync mi olacak yoksa database mi? bu durumlarda hangiisi onerilir?

                sineld Ben en iyisi sizi boşa uğraştırmayayım direkt istediğiniz cevabı vereyim: Her bir URL'deki veriyi çekip kaydeden işi kuyruğa atacaksınız, arkada çekip kaydedecek.

                ScrapUrl::dispatch("http://site.com/?page=1")
                ScrapUrl::dispatch("http://site.com/?page=2")
                ScrapUrl::dispatch("http://site2.com/?page=1")
                ...

                  CodeWriteson Ben Redis kullanıyorum, memnunum. Sync demek kuyruk yok, direkt ateşle demek 🙂 Redis imkanı varken database tavsiye etmiyorum.

                    mgsmus Redis olurken local de ve sunucuda ayri ayri kurulummu yapmam gerecek?

                      mgsmus Hocam oncelikle cok tesekkurler soyledikleriniz cok yardimci oldu. Calisirken biraz arastirma falan yaptim ve boyle bir seyle karsilastim.

                      Queue::push(new InvoiceEmail($order));

                      Bus::dispatch(new InvoiceEmail($order));

                      mesela bunlar ne is yapiyor? yani anladim queue ya job ekliyor. Amma anlamadim kullanilma yerlerini. Mesela benim istedigim ornekte gereklimi kullanmak? Degilse ne zaman gerekli

                        • mgsmus

                          Seviye 1384
                        • Düzenlendi

                        CodeWriteson Bunlar eskiden Job mantığı yokken kullanılıyordu, size gerekli değil, arka planda aktifler sadece.

                        Siz bir Job'ı ShouldQueue arayüzü ile gerçeklediğinizde dispatch(new InvoiceEmail($order)) yaptığınızda otomatik olarak kuyruğa alır, Queue::push yapmanıza gerek kalmaz. Ayrıca dispatch(new InvoiceEmail($order)) ya da InvoiceEmail::dispatch($order) şeklinde Job'ı ateşleyebiliyorsunuz, Bus::dispatch yapmanıza gerek yok.

                        Güncel dokümanlarda olanın dışına çıkmamaya çalışın, kafanız karışmasın. Tam 5 yıl önceki bilgiyi bulup getirmişsiniz.

                          mgsmus Eyvallah. Once guncel dokumanlara bakmistim zaten o yuzden bu karsima cikinca tam anlayamadim. Tesekkurler bilgi icin.

                          mgsmus Hocam Ben islem bitdikden sonra Job islemleri kullaniciya bildirim gondermek istiyorum. Job un bitdigini AppServiceProviderde Queue nun ozellikleriylemi yakalicam yoksa baska bir yolu varmi?

                            CodeWriteson AppServiceProvider'da da yaptırabilirsiniz Job içerisinde en son işlem olarak da. Eğer Job'ın kendisiyle ilgili işlemler yapmak istiyorsanız AppServiceProvider'da Queue kullanmak mantıklı ama yapacağınız iş Job ile değil de Job'ın içeride yaptığı iş ile alakalı ise Job içerisinde yapılması daha iyi olur diye düşünüyorum.