PHP file_get_contents тайм-аут локального файла (NFS / монтирование)

Я хотел бы знать, как установить тайм-аут для локального файла с помощью file_get_content (не HTTP uri). Иногда раздел монтирования NFS очень медленный, и я предпочитаю отказаться после тайм-аута (например, 5 секунд),

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

Я читал ответы на другие подобные вопросы, но думаю, что решения работают только с HTTP, а не для локальных файлов:

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

Я также полагаю, что это решение не для меня, оно тоже для Интернета, верно?

ini_set('default_socket_timeout', 900);

person NicoMinsk    schedule 10.11.2016    source источник
comment
Покажите нам команду монтирования или запись /etc/fstab   -  person Ruslan Osmanov    schedule 10.11.2016
comment
Запись в fstab: 192.168.0.167:/data / mnt / photo по умолчанию nfs 0 0   -  person NicoMinsk    schedule 10.11.2016


Ответы (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, а родительский может убить это через определенный промежуток времени.

person Ruslan Osmanov    schedule 10.11.2016
comment
Спасибо, в данном случае я использую php + apache, вилка недоступна. Я посмотрю на параметры монтажа, если нет PHP-решения! Спасибо - person NicoMinsk; 10.11.2016

Вы можете установить поток в неблокирующий режим с помощью 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');
person Federkun    schedule 10.11.2016
comment
хорошая идея, это может помочь другим людям, но в моем случае это не работает, потому что проблема не в том, что нужно читать большой и длинный файл, а в том, что монтирование не отвечает (так что чтение недоступно), спасибо - person NicoMinsk; 10.11.2016