• 07-12-2024, 23:36:00
    #1
    Merhaba arkadaslar, bir REST API'sinden veri cekerken cURL kullaniyorum ve soyle bir problemle karsilastim:
    API'den gelen cevap bazen beklenenden uzun surede geliyor ve CURLOPT_TIMEOUT ayari devreye giriyor. Ancak, bu timeout'u yonetmek istedigim bir senaryom var. Diyelim ki ilk istekte timeout oldu, ben otomatik olarak ayni istegi tekrar yapmak istiyorum. Fakat ayni anda birden fazla thread/process calisiyorsa, bu yeniden denemeler concurrency problemlerine neden oluyor gibi. kod su sekilde;

    function fetchData($url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $response = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch);
    
        if ($error) {
            // Timeout veya baska bir hata
            // Burada yeniden deneme yapmam gerekiyor
        }
    
        return $response;
    }
    Bu yeniden deneme mekanizmasini duzgun bir sekilde nasil tasarlayabilirim? Ayrica ayni URL'e birden fazla process'in ayni anda yeniden deneme yapmasini engellemek icin onerileriniz var mi?
  • 07-12-2024, 23:41:44
    #2
    Bu şekilde olabilir;

    function fetchData($url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $response = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch);
     
        if ($error) {
            return fetchData($url)
        }
     
        return $response;
    }
  • 08-12-2024, 00:01:22
    #3
    Hocam, en basit ve hızlı çözüm dosya tabanlı kilit mekanizması. Hem ekstra sistem kurulumuna gerek yok, hem de bir URL'nin aynı anda birden fazla işlem tarafından yeniden denenmesini kolayca engelleyebilirsin.
    function fetchData($url, $maxRetries = 3, $retryDelay = 1000000) {
        $lockFile = sys_get_temp_dir() . '/lock_' . md5($url) . '.lock';
    
        // Lock dosyasını kontrol et
        if (file_exists($lockFile)) {
            echo "URL şu an işleniyor, bekle...\n";
            return false; // Başka bir işlem bu URL'yi işliyor
        }
    
        // Lock dosyasını oluştur
        file_put_contents($lockFile, "1");
    
        $retryCount = 0;
        $response = false;
    
        try {
            while ($retryCount < $maxRetries) {
                $ch = curl_init($url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 5);
                $response = curl_exec($ch);
                $error = curl_errno($ch);
                curl_close($ch);
    
                if (!$error) {
                    break; // Başarılı, döngüyü kır
                }
    
                $retryCount++;
                usleep($retryDelay); // Yeniden denemeden önce bekle
            }
        } finally {
            unlink($lockFile); // İş bitti, lock'u kaldır
        }
    
        return $response;
    }
    Uzun vadede daha büyük sistemlere geçersen, veritabanı ya da Redis gibi bir şey düşünebilirsin.