2016-11-10 1 views
2

Je voudrais savoir comment définir un délai d'attente sur un fichier local avec file_get_content (pas HTTP uri), Parfois, la partition de montage NFS est très lente et je préfère abandonner après un certain temps (5 secondes par exemple),PHP file_get_contents timeout "fichier local" (NFS/mount)

file_get_contents("/mnt/photo/photo.jpg"); 

Je lis des réponses à d'autres questions similaires, mais je suppose que les solutions fonctionnent uniquement avec HTTP, et non pour les fichiers locaux:

$ctx = stream_context_create(array('http'=>array('timeout' => 1200))); 

J'ai aussi supposons que cette solution ne soit pas pour moi, c'est aussi pour le Web, n'est-ce pas?

ini_set('default_socket_timeout', 900); 
+0

Montrez-nous la commande mount, ou l'entrée '/ etc/fstab' –

+0

L'entrée dans fstab: 192.168.0.167:/data/mnt/photo nfs par défaut 0 0 – NicoMinsk

Répondre

1

Je crains, vous ne pouvez pas contrôler le NFS via les délais d'attente PHP, comme les options de protocole NFS sont contrôlés uniquement par des options de montage. PHP n'a aucune idée si un fichier est sur NFS, ou sur un disque dur local. Je crois, il y a des manières de déterminer le fait qu'un dossier est sur NFS, mais il ne nous donnera pas le contrôle sur les délais d'attente.

Il existe deux types de délais d'attente dans NFS: mineur et majeur. Un dépassement de délai mineur se produit lorsqu'aucune confirmation n'est reçue du serveur dans le délai spécifié dans les options de montage (timeo). Ensuite, l'opération est réessayée et le délai d'expiration est doublé. Un délai d'attente important se produit lorsque l'intervalle de délai atteint 60 secondes. Ce qui se passe ensuite dépend d'autres options.

Par défaut, le délai d'attente d'origine est doublé et les tentatives se poursuivent indéfiniment. Il est dit qu'un volume est monté en dur (l'option hard est activée par défaut). Si le volume est monté avec l'option soft, un délai d'attente majeur entraînera une erreur d'E/S. Vous devriez envisager un montage en douceur. Cependant, notez que le délai d'expiration par défaut est seulement (0,7 secondes), ce qui est probablement un peu trop petit pour un montage en douceur. Vous devez estimer le temps d'attente possible et ajuster l'option timeo en conséquence.

Une autre option intéressante est intr, qui est supposée permettre l'interruption des opérations NFS en attente. Cependant, cette option est obsolète après la version 2.6.25 du noyau. Seul SIGKILL peut interrompre une opération NFS. Vous souhaiterez peut-être implémenter un processus de surveillance à l'aide de la fonction fork(). Le processus enfant peut exécuter une opération NFS et le parent peut le faire après une certaine période de temps.

+0

Merci, Dans ce cas j'utilise php + apache, la fourchette n'est pas disponible. Je regarderai les paramètres de montage si aucune solution PHP n'est disponible! Merci – NicoMinsk

1

Vous pouvez régler le flux en mode non-bloquant avec stream_set_blocking et essayez de lire le fichier jusqu'à ce que le délai d'attente. Quelque chose comme:

function readReallyBigFile($path, $timeoutSeconds = 5) { 
    if (false === $stream = fopen($path, "r")) { 
     throw new \RuntimeException('Cannot open file'); 
    } 

    stream_set_blocking($stream, 0); 

    $timeout = time(); 

    $contents = ''; 
    while (!feof($stream)) { 
     $contents .= fread($stream, 8192); 
     if ((time() > $timeout + $timeoutSeconds)) { 
      throw new \RuntimeException('Timeout reached out'); 
     } 
    } 

    fclose($stream); 

    return $contents; 
} 

$img = readReallyBigFile('/mnt/photo/photo.jpg'); 
+0

bonne idée, ça pourrait aider d'autres personnes, mais ça ne fonctionne pas dans mon cas, car le problème n'est pas dû à un gros fichier long à lire, mais à cause de ne pas répondre mount (donc pas de lecture disponible), Merci – NicoMinsk