Откройте порт Python из Erlang: нет ответных сообщений

Основываясь на главе 12 книги OTP in Action и книге Чезарини, я написал этот код Erlang:

Эрланг:

p(Param) ->

    ?DBG("Starting~n", []),

    Cmd = "python test.py",

    Port = open_port({spawn,Cmd}, [stream,{line, 1024},  exit_status]),
    ?DBG("Opened the port: ~w~n", [Port]),

    Payload = term_to_binary(list_to_binary(integer_to_list(Param))),
    erlang:port_command(Port, Payload),

    ?DBG("Sent command to port: ~w~n", [Payload]),
    ?DBG("Ready to receive results for command: ~w~n", [Payload]),

    receive
        {Port, {data, Data}} ->
            ?DBG("Received data: ~w~n", [Data]),
            {result, Text} = binary_to_term(Data),
            Blah = binary_to_list(Text),
            io:format("~p~n", [Blah]);
        Other ->
            io:format("Unexpected data: ~p~n", [Other])

    end.

Питон:

import sys
def main():
    while True:
        line = sys.stdin.readline().strip()
        if line == "stop-good":
                return 0
        elif line == "stop-bad":
                return 1
        sys.stdout.write("Python got ")
        sys.stdout.write(line)
        sys.stdout.write("\n")
        sys.stdout.flush()
if __name__ == "__main__":
 sys.exit(main())

Код Erlang приостанавливается в предложении получения - он никогда не получает никаких сообщений.

Я также проверил Python из обычной оболочки Linux — он распечатывает каждый пользовательский ввод (1 — «Python получил 1»).

Где здесь ошибка? Почему мой код Erlang ничего не возвращает?


person skanatek    schedule 13.10.2011    source источник


Ответы (2)


Есть два момента:

  • убедитесь, что Python не буферизует ваш вывод, попробуйте запустить python -u в open_port
  • использование term_to_binary/1 и binary_to_term/1 не будет работать, так как предполагается, что Python может кодировать/декодировать Внешний формат термина Erlang, что, похоже, не так. Если вы хотите пойти по этому пути, посетите ErlPort.
person gleber    schedule 14.10.2011

Содержит ли ваш Param ограничитель команд для Python? (в этом случае я предполагаю новую строку, "\n"). Кроме того, list_to_binary/1, а затем term_to_binary/1 кажется неправильным. term_to_binary/1 напрямую (включая новую строку) должно быть достаточно.

person Kreisquadratur    schedule 13.10.2011