Длина передачи данных порта Erlang

#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 не поддерживает это, вам придется каждый раз перезапускать его.