Nasıl birden fazla soket bağlantıları açık ve PHP geri çağrıları yapmak için

3 Cevap php

Ben öğelerin bir kuyruk işler bazı kod yazıyorum. Çalışır yolu şudur:

  1. Get the next item flagged as needing to be processed from the mysql database row.
  2. Request some info from a google API using Curl, wait until the info is returned.
  3. Do the remainder of the processing based on the info returned.
  4. Flag the item as processed in the db, move onto the next item.

Sorun adım # 2. Google bazen benim senaryom durdurdu kalır ve beklemek zorundadır, bu süre içinde, istenen bilgi dönmek için 10-15 saniye sürer olmasıdır.

Bunun yerine aşağıdakileri yapmak için kodunu değiştirmek ben merak ediyorum:

  1. Get the next 5 items to be processed as usual.
  2. Request info for items 1-5 from google, one after the other.
  3. When the info for item 1 is returned, a 'callback' should be done which calls up a function or otherwise calls some code which then does the remainder of the processing on items 1-5.
  4. And then the script starts over until all pending items in db are marked processed.

Nasıl böyle bir şey elde edilebilir?

3 Cevap

Sen 2 işlem türlerinde bu ayırabilirsiniz.

  1. İşçi süreci (çalışan birçoğu vardır):, işlenen veritabanı satır bilen yapar ve Google API çağrısı için bekler, ve sonra iş yapar, ve veritabanına sonuçlarını kaydeder.

  2. Zamanlayıcı (ve tek): periyodik (diyelim ki, her birkaç saniyede) çekleri orada yapılacak bir iş, ve N çalışan işçiler (5 veya ne olursa olsun optimal) olmadığından emin yaparsa. Daha sonra N işçiler çalıştırıyorsanız, tüm iş bitene kadar, N tutmak için (exec ile) daha fazla işçi başlar.

Bu zarif bir yaklaşım olup olmadığını ben gerçekten bilmiyorum, ama teoride her öğe için PHP işlemi çatal () çatal kullanabilirsiniz. Bu, tüm kod tek bir dosyada olmasını sağlayacak.

// Get items from DB
$items = get_items_from_db();
foreach($items as $item) {
    $pid = pcntl_fork();
    if($pid == -1) die("Couldn't fork!");
    if(!$pid) {
      // Process the item in the child process
      process_item($item);
      exit();
    }
}
// Wait for all child processes to end
pcntl_wait();
// We're done!

Ama evet, bu çözüm büyük olasılıkla bazı insanlar çığlık yapacak ;)

Ben belirli bir madde için aynı makinede bir çocuk komut arayacak bir ana komut dosyası oluşturabilirsiniz düşünüyorum. Çocuk komut google API isteği göndermek ve buna göre çalışır.