#erlang #port
#erlang #порт
Вопрос:
Я пытаюсь оценить php-код через erlang, используя порты erlang. Проблема в том, что когда оцениваемые данные больше, я получаю ошибку синтаксического анализа из php. Но если данных меньше, то я получаю правильный вывод. Я думаю, что когда длина данных больше, erlang усекает данные перед их отправкой в php для оценки. Существует ли какое-либо ограничение на длину данных, которые могут быть отправлены или получены на порту erlang. Или эта ошибка вызвана какой-то другой причиной?
Я использую open_port (имя порта, настройки портов) для открытия нового порта, а в настройках портов я устанавливаю [{packet, 4}, exit_status] в качестве параметров порта.
Ответ №1:
{packet, 4}
Кортеж говорит, что программа, запущенная для обработки другого конца порта, ожидает данные в форме с префиксом длины 4 байта. Я ничего не вижу в документах для php(1)
программы, в которой говорится, что она знает, как обращаться с такими данными. Вероятно, единственная причина, по которой это работает для коротких входных данных, заключается в том, что префикс длины выглядит как ASCII, если вы прищуриваетесь, пока отправляемые вами данные меньше 127 байт. Как только вы перейдете к этому, PHP, вероятно, столкнется с ошибкой декодирования UTF-8.
Я почти уверен, что вы хотите сказать spawn
здесь вместо этого. Это обеспечивает стандартное взаимодействие с Unix-подобным каналом: данные, отправленные по порту, отправляются в stdin в запущенном процессе, и все, что он отправляет в стандартный вывод, возвращается в ваш процесс Erlang.
Единственная проблема при выполнении этого способа заключается в том, что он повторно запускается php(1)
при каждой транзакции. Это может показаться дорогостоящим, но это не так уж плохо в любой системе типа Unix из-за относительной эффективности fork(2)
системного вызова. Если вы используете Windows или провели сравнительный анализ и обнаружили, что вам действительно нужно создать систему, подобную FastCGI, вам может не повезти. Кажется, что нет libphp
возможности встроить PHP в программу, которую вы пишете для обработки пакетного ввода, и нет способа запустить php(1)
таким образом, чтобы он оставался активным на другом конце порта. Возможно, вам лучше переключиться на собственную систему шаблонов Erlang.
Также обратите внимание, что exit_status
атом, переданный open_port()
, ничего не делает, если вы не используете spawn
.
Комментарии:
1. Извините за недостающие детали. Да, я использую spawn для имени порта, и вы правы в том, что отправленные данные отправляются в stdin, а php отправляет в стандартный вывод, и это возвращается в процесс erlang. Но я не понял, когда вы сказали «Единственная проблема, при которой это делается таким образом, заключается в том, что он повторно запускает php (1) при каждой транзакции». Не могли бы вы, пожалуйста, объяснить это утверждение?
2. Я имею в виду, что
php(1)
это не вернет обработанный вывод (по крайней мере, не весь), пока он не получит EOF в своем stdin, что не произойдет, пока ваша программа Erlang не вызоветport_close()
. Затем вам нужно открыть новый порт PHP для обработки другого документа. Было бы эффективнее, если бы вы могли поддерживать процесс PHP в рабочем состоянии, для чего и предназначены все разделители пакетов и строк при открытии порта: способ отличить одну транзакцию от следующей. Поскольку автономный интерпретатор PHP не поддерживает это, вам придется каждый раз перезапускать его.