PHP file get contents timeout "локальный файл" (NFS / mount)
Я хотел бы знать, как установить тайм-аут для локального файла с file_get_content (не HTTP uri), Иногда NFS mount partition очень медленный, и я предпочитаю сдаваться после тайм-аута (5s для exemple),
file_get_contents("/mnt/photo/photo.jpg");
Я читал ответы на другие подобные вопросы, но думаю, что решения работают только с HTTP, а не для локальных файлов:
$ctx = stream_context_create(array('http'=>array('timeout' => 1200)));
Я также предполагаю, что это решение не для меня, это также для веба, верно?
ini_set('default_socket_timeout', 900);
2 ответа:
Боюсь, что вы не можете управлять таймаутами NFS через PHP, так как параметры протокола NFS управляются только через опции монтирования. PHP понятия не имеет, находится ли файл на NFS или на локальном жестком диске. Я считаю, что есть способы определить тот факт, что файл находится на NFS, но это не даст нам контроль над таймаутами.
В NFS существует два типа таймаутов: минорный имажорный . Незначительный тайм-аут происходит, когда в течение этого тайм-аута от сервера не получено никакого подтверждения указывается в параметрах монтирования (timeo
). Затем операция повторяется, и тайм-аут удваивается. Основной тайм-аут наступает, когда интервал тайм-аута достигает 60 секунд. То, что произойдет дальше, зависит от других вариантов.По умолчанию исходный тайм-аут удваивается, и повторные попытки продолжаются бесконечно. Говорят, что Том жестко монтируется (опция
hard
включена по умолчанию). Если том монтируется с параметромsoft
, основной тайм-аут приведет к ошибке ввода-вывода. Вы должны рассмотреть возможность мягкого монтажа. Однако обратите внимание, что тайм-аут по умолчанию равен только 7(0.7 секунд), который, вероятно, немного слишком мал для мягкого монтажа. Вы должны оценить возможное время ожидания и соответствующим образом настроить параметрtimeo
.Другим интересным вариантом является
intr
, который, как предполагается, позволяет прерывать отложенные операции NFS. Однако эта опция устарела после версии ядра 2.6.25. ТолькоSIGKILL
может прервать операцию NFS. Возможно, вы захотите реализовать сторожевой процесс с помощью функцияfork()
. Дочерний процесс может выполнить операцию NFS, и родитель может убить его через определенный промежуток времени.
Вы можете установить поток в неблокирующий режим с помощью
stream_set_blocking
и попытаться прочитать файл до истечения времени ожидания. Что-то вроде: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');